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')
'&#40960;abcd&#1972;'
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]

Podobne dokumenty