Handout
Transkrypt
Handout
Obliczenia Symboliczne I Przetwarzanie Tekstu Unicode >>> s1 = unicode('abcdef') >>> s2 = u'abcdef' Unicode >>> unicode('\x80abc', errors='strict') Traceback (most recent call last): File "<stdin>", line 1, in ? UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0: ordinal not in range(128) Unicode >>> >>> unicode('\x80abc', errors='replace') u'\ufffdabc' >>> unicode('\x80abc', errors='ignore') u'abc' >>> unichr(40960) u'\ua000' >>> ord(u'\ua000') 40960 Unicode >>> s = u'Was ever feather so lightly blown to and fro as this multitude?' >>> s.count('e') 5 >>> s.find('feather') 9 Unicode >>> s.find('Was\x9f') Traceback (most recent call last): File "<stdin>", line 1, in ? UnicodeDecodeError: 'ascii' codec can't decode byte 0x9f in position 3: ordinal not in range(128) >>> s.find(u'Was\x9f') -1 Unicode >>> u = unichr(40960) + u'abcd' + unichr(1972) >>> u.encode('utf-8') '\xea\x80\x80abcd\xde\xb4' >>> u.encode('ascii') Traceback (most recent call last): File "<stdin>", line 1, in ? UnicodeEncodeError: 'ascii' codec can't encode character '\ua000' in position 0: ordinal not in range(128) >>> u.encode('ascii', 'replace') '?abcd?' >>> u.encode('ascii', 'xmlcharrefreplace') 'ꀀabcd޴' Unicode michal@michal-laptop:~$ cat test.py # -*- coding: utf-8 -*print u"ółążśźóćł" Unicode michal@michal-laptop:~$ python test.py ółążśźóćł Unicode michal@michal-laptop:~$ python test.py > wynik michal@michal-laptop:~$ cat wynik Traceback (most recent call last): File "test.py", line 3, in <module> print u"ółążśźóćł" UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-8: ordinal not in range(128) Unicode # -*- coding: utf-8 -*import sys import codecs print sys.stdout.encoding #sys.stdout.encodin==None: ... to jest zmienna typu readonly sys.stdout = codecs.getwriter('utf8')(sys.stdout) print u"ółążśźóćł" Unicode uni = u"Hello\u001A\u0BC3\u1451\U0001D10CUnicode" utf8_string = uni.encode('utf-8') # naively convert back to Unicode uni = unicode(utf8_string) Unicode Traceback (most recent call last): File "t6.py", line 5, in ? uni = unicode(utf8_string) UnicodeDecodeError: 'ascii' codec can't decode byte 0xe0 in position 6: ordinal not in range(128) Unicode uni = u"Hello\u001A\u0BC3\u1451\U0001D10CUnicode" utf8_string = uni.encode('utf-8') # have to decode with the same codec the encoder used! uni = unicode(utf8_string,'utf-8') print "Back from UTF-8: ",repr(uni) Wyrażenia regularne Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. -- Jamie Zawinski, '<alt.religion.emacs>' (08/12/1997) Wyrażenia regularne [ ... ] - zakres znaków („klasa”) ^ - operator dopełnienia mnogościowego . - dowolny znak ale nie koniec linii \d – cyfry – odpowiada [0-9] \D – nie-cyfry – odpowiada [^0-9] \s – biały znak – odpowiada [ \t\n\r\f\v] \S – nie-biały znak – odpowiada [^ \t\n\r\f\v]. \w – znak alfanumeryczny – odpowiada [a-zA-Z0-9_] \W – znak niealfanumeryczny – odpowiada [^a-zA-Z0-9_] Wyrażenia regularne | - „lub” ab|bc ^ - oznaczenie początku linii ^From: $ - oznaczenie końca linii End.$ \A – początek \Z – koniec \b – granica słowa (! - uwaga na backspace) >>> p = re.compile(r'\bclass\b') >>> p = re.compile('\bclass\b') \B negacja \b Wyrażenia regularne * - powielenie 0 lub więcej razy („gwiazdka Kleene'a”) >>> p = re.compile('(ab)*') >>> print p.match('ababababab').span() (0, 10) {min,max} a/{1,3}b -> "a/b", "a//b", and "a///b". + - „Plus Kleene'a” - 1 lub więcej ? - 0 lub 1 razy Wyrażenia regularne Niezachłanne dopasowania *? +? ?? {m,n}? s = '<html><head><title>Title</title>' print re.match('<.*>', s).group() <html><head><title>Title</title> print re.match('<.*?>', s).group() <html> Grupowanie Grupowanie >>> p = re.compile('(a(b)c)d') >>> m = p.match('abcd') >>> m.group(0) 'abcd' >>> m.group(1) 'abc' >>> m.group(2) 'b' Grupowanie Nie przechwytująca grupa (?:foo) re.match("([abc])+", "abc").groups() ('c',) re.match("(?:[abc])+", "abc").groups() () Nazwana grupa (?P<name>...) >>> p = re.compile(r'(?P<word>\b\w+\b)') >>> m = p.search( '(((( Lots of punctuation )))' ) >>> m.group('word') 'Lots' Powielenie (?P=<name>) >>> p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)') Grupowanie Lookahead pozytywne (?=...) Lookahead negatywne Wszystkie pliki z wyjątkiem bat i exe .*[.](?!bat$|exe$).*$ Negative look behind (?<!regex) – dopasuj jeśli zaraz poprzedzającym nie był regex Positive look behind (?<=regex) Warunkowe wyrażenia Etc .... Wyrażenia regularne >>> import re >>> p = re.compile('ab*') >>> print p <re.RegexObject instance at 80b4150> >>> p = re.compile('ab*', re.IGNORECASE) Wyrażenia regularne Cel: \section Wyrażenie: \\section Stała łańcuchowa: \\\\section Notacja „raw string”: „ab*” → r”ab*” „\\\\section” → r”\\section” „\\w+\\s+\\1” → r”\w+\s+\1” Wyrażenia regularne >>> import re >>> p = re.compile('[a-z]+') >>> p <_sre.SRE_Pattern object at 80c3c28> Wyrażenia regularne match() Szuka dopasowania na początku napisu search() Szuka dopasowania, także w środku findall(), finditer() Szuka dopasowań, zwraca, odpowiednio, listę lub iterator Wyrażenia regularne >>> print p.match("") None >>> print m = p.match( 'ala') <_sre.SRE_Match object at 80c4f68> Wyrażenia regularne m.group() Wypisuje dopasowany napis m.start(), m.end(), m.span() Podaje indeksy miejsca dopasowanego Wyrażenia regularne >>> p = re.compile('\d+') >>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...') >>> for match in iterator: ... print match.span() ... (0, 2) (22, 24) (29, 31) Funkcje modułu re.match( regex, string ) re.search (regex, string ) re.sub() ... etc. Flagi compile re.compile( regex, flags) DOTALL , S re.compile(„.*”, re.S) IGNORECASE, I LOCALE, L MULTILINE, M VERBOSE, X re.compile( „a*”, re.I | re.M ) re.compile(„(?xm)a*”) Wyrażenia regularne re.VERBOSE pat = re.compile(r"\s*(?P<header>[^:]+)\s*:(?P<value>.*?)\s*$") Wyrażenia regularne pat = re.compile(r""" \s* # Skip leading whitespace (?P<header>[^:]+) # Header name \s* : # Whitespace, and a colon (?P<value>.*?) # The header's value -- *? used to # lose the following trailing whitespace \s*$ """, re.VERBOSE) # Trailing whitespace to end-of-line Podstawienie >>> p = re.compile( '(blue|white|red)') >>> p.sub( 'colour', 'blue socks and red shoes') 'colour socks and colour shoes' >>> p.sub( 'colour', 'blue socks and red shoes', count=1) 'colour socks and red shoes' >>> p = re.compile('x*') >>> p.sub('-', 'abxd') '-a-b-d-' Podstawienie Podstawienie z dopasowaniem >>> p = re.compile('section{ ( [^}]* ) }', re.VERBOSE) >>> p.sub(r'subsection{\1}','section{First} section{second}') 'subsection{First} subsection{second}' >>> p = re.compile('section{ (?P<name> [^}]* ) }', re.VERBOSE) >>> p.sub(r'subsection{\1}','section{First}') 'subsection{First}' >>> p.sub(r'subsection{\g<1>}','section{First}') 'subsection{First}' >>> p.sub(r'subsection{\g<name>}','section{First}') 'subsection{First}' Podstawienie >>> def repl(m): ... inner_word = list(m.group(2)) ... random.shuffle(inner_word) ... return m.group(1) + "".join(inner_word) + m.group(3) >>> text = "Professor Abdolmalek, please report your absences promptly." >>> re.sub("(\w)(\w+)(\w)", repl, text) 'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.' Paragraf w lewo #flush left from re import findall,sub indent = lambda s: reduce(min,map(len,findall('(?m)^ *(?=\S)',s))) flush_left = lambda s: sub('(?m)^ {%d}' % indent(s),'',s) print flush_left(sys.stdin.read()) Usuwanie duplikatów import sys, re, glob for pat in sys.argv[1:]: for file in glob.glob(pat): newfile = 1 for para in open(file).read().split('\n\n'): dups = re.findall(r'(?m)(^.*(\b\w+\b)\s*\b\2\b.*$)', para) if dups: if newfile: print '%s\n%s\n' % ('-'*70,file) newfile = 0 for dup in dups: print '[%s] -->' % dup[1], dup[0]