Wykład 8.
Przetwarzanie tekstu
● Wyrażenia regularne
● Biblioteka url ib
● Parsowanie html'a
● XML
c:\> dir *.exe $ rm *.tmp
● 'alamakota'
● '(hop!)*'
{ ' , 'hop!', 'hop!hop!',... }
● 'br+um'
{ 'brum', 'brrum', 'brrrum' }
wyrażenia regularnego
Automat
Wyszukiwanie a dopasowanie import re
automat = re.compile('brr+um')
if automat.match('brrrrum!!!'): print 'pasuje'
if automat.search('Autko robi brrrrum!!!'): print 'pasuje'
res = automat.search('brrrum!!!')
● res.group() # dopasowany tekst
● res.span() # para (początek, koniec)
Znaleźć na stronie html'owej wszystkie odwołania do innych stron
adres = '([a-zA-Z]+\.)*[a-zA-Z]+'
http = 'http:\\' + adres
automat = re.compile(http)
tekst = fh.read()
[ url.group() for url in automat.finditer(tekst) ]
● |
● {m,n}
● {m}
● .
● ?
● ^
● \d – dowolna cyfra
● \w – znak alfanumeryczny (zależy od ustawień LOCALE)
● \Z – koniec napisu
'Imię\tNazwisko\n'
print 'Tabulator to znak \\t'
'c:\\WINDOWS\\win.ini'
\ w wyrażeniach regularnych Zagadka:
Jak znaleźć w tekście '\['
re.match('\[', '\[')
re.match('\\[', '\[')
re.match('\\\[', '\[')
re.match('\\\\[', '\[')
re.match('\\\\\[', '\[')
Raw tekst:
re.match(r'\\\[', '\[')
Zadanie: z daty w formacie '20061204'
wyciągnąć dzień, miesiąc i rok.
(?P< nazwa> regexp)
tekst = 'abbabbba'
wzor = 'a(b*)a.*(a)'
aut = re.compile(wzor)
res = aut.match(tekst)
print res.groups()
Wynik: ('bb', 'a')
tekst = '20061204'
wzor = r'(?P<rok>\d{4})(?P<mies>\d{2})(?
P<dzien>\d{2})'
aut = re.compile(wzor)
res = aut.search(tekst)
print res.group('rok'), res.group('mies')
Ściąganie stron przez http i https import url ib
in_stream = url ib.urlopen('http://www.python.org') doc = f.read()
f.close()
● in_stream.readlines()
● for line in in_stream: print line,
import sgml ib
class sgml ib.SGMLParser:
def start_ tag(self, attrs):
def end_ tag(self):
def handle_data(self, data)
Przykładowa implementacja class MyParser(sgml ib.SGMLParser):
def start_a(self, attrs):
for (atr, val) in attrs:
if atr == 'href': print val
p = MyParser()
p.feed(doc)
p1.close()
Extensible Markup Language
<?xml version="1.0" encoding="UTF-8"?>
<biblioteka>
<ksiazka egzemplarze="3">
<autor>Ascher, Martel i, Ravenscroft</autor>
<tytul>Python. Receptury</tytul>
</ksiazka>
<ksiazka>
<autor/>
<tytul>Python. Od podstaw</tytul>
</ksiazka>
</biblioteka>
Schemat przetwarzania:
● Elementy pliku są kolejno wczytywane
● Dla każdego elementu wywoływana jest
odpowiednia funkcja
class saxutils.DefaultHandler:
def startElement(self, name, attrs): pass def startDocument(self): pass
def endElement(self, name): pass
def endDocument(self): pass
def characters(self, value): pass
class SaxReader(saxutils.DefaultHandler): def characters(self, value):
print value
def startElement(self, name, attrs):
for x in attrs.keys():
print x, '=', attrs[x]
from xml.sax import make_parser
from xml.sax.handler import
feature_namespaces
from xml.sax import saxutils
parser = make_parser()
parser.setFeature(feature_namespaces, 0) dh = SaxReader()
parser.setContentHandler(dh)
parser.parse(fh)
● Przetwarzanie w trybie 'do odczytu'
● Przetwarzanie liniowe
● SAX jest szybki, nie wymaga dużej pamięci
● Dokument jest pamiętany w całości jako drzewo
● Dokument (drzewo) można modyfikować
● Przetwarzanie sporo czasu i pamięci, całe drzewo jest przechowywane w pamięci
import xml
doc = xml.dom.minidom.parse('content.xml')
nodeType
nodeName
nodeValue
parentNode
childNodes
firstChild
lastChild
previousSibling
nextSibling
attributes
appendChild(newChild)
removeChild(oldChild)
replaceChild(newChild, oldChild)
new = document.createElement('chapter') new.setAttribute('number', '5')
document.documentElement.appendChild(new)
from xml.dom.NodeFilter import NodeFilter reader = Sax2.Reader()
doc = reader.fromStream(open('plik.xml', 'r'))
walker =
doc.createTreeWalker(doc.documentElement, NodeFilter.SHOW_ALL, None, 0)
while 1:
print walker.currentNode.nodeName
next = walker.nextNode()
if next is None: break
Selekcja ścieżek w drzewie
from xml import xpath
nodes = xpath.Evaluate('ksiazka/autor', doc.documentElement)