Kurs języka Python Wykład 8. Przetwarzanie tekstu Wyrażenia regularne Biblioteka urllib Parsowanie html'a XML
Wyrażenia regularne c:\> dir *.exe $ rm *.tmp
Wyrażenia regularne 'alamakota' '(hop!)*' { '', 'hop!', 'hop!hop!',... } 'br+um' { 'brum', 'brrum', 'brrrum' }
Algorytm rozpoznawania 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'
Klasa MatchObject res = automat.search('brrrum!!!') res.group() # dopasowany tekst res.span() # para (początek, koniec)
Większe zadanie Znaleźć na stronie html'owej wszystkie odwołania do innych stron
Wyrażenie opisujące odwołanie www.ii.uni.wroc.pl adres = '([a-za-z]+\.)*[a-za-z]+'
Pełne (prawie) wyrażenie http = 'http:\\' + adres automat = re.compile(http) tekst = fh.read()
Lista wszystkich odwołań [ url.group() for url in automat.finditer(tekst) ]
Przegląd metaznaków {m,n} {m}.? ^
Skróty \d dowolna cyfra \w znak alfanumeryczny (zależy od ustawień LOCALE) \Z koniec napisu
Problem z ukośnikiem \ '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('\\\\\[', '\[') Próby rozwiązania
Inne rozwiązanie Raw tekst: re.match(r'\\\[', '\[')
Grupowanie wyrażeń Zadanie: z daty w formacie '20061204' wyciągnąć dzień, miesiąc i rok.
Wyrażenie grupujące (?P<nazwa>regexp)
Trochę więcej o grupach tekst = 'abbabbba' wzor = 'a(b*)a.*(a)' aut = re.compile(wzor) res = aut.match(tekst) print res.groups() Wynik: ('bb', 'a')
Rozwiązanie 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 urllib in_stream = urllib.urlopen('http://www.python.org') doc = f.read() f.close()
Strumień in_stream.readlines() for line in in_stream: print line,
Parsowanie html import sgmllib class sgmllib.sgmlparser: def start_tag(self, attrs): def end_tag(self): def handle_data(self, data)
Przykładowa implementacja class MyParser(sgmllib.SGMLParser): def start_a(self, attrs): for (atr, val) in attrs: if atr == 'href': print val
p = MyParser() p.feed(doc) p1.close() Uruchomienie
XML Extensible Markup Language
Przykład <?xml version="1.0" encoding="utf-8"?> <biblioteka> <ksiazka egzemplarze="3"> <autor>ascher, Martelli, Ravenscroft</autor> <tytul>python. Receptury</tytul> </ksiazka> <ksiazka> <autor/> <tytul>python. Od podstaw</tytul> </ksiazka> </biblioteka>
SAX - Simple API for XML Schemat przetwarzania: Elementy pliku są kolejno wczytywane Dla każdego elementu wywoływana jest odpowiednia funkcja
From xml.sax import * 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
Schemat programu class SaxReader(saxutils.DefaultHandler): def characters(self, value): print value
Start element def startelement(self, name, attrs): for x in attrs.keys(): print x, '=', attrs[x]
Inicjowanie 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)
Cechy SAX Przetwarzanie w trybie 'do odczytu' Przetwarzanie liniowe SAX jest szybki, nie wymaga dużej pamięci
Document Object Model (DOM) 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
Utworzenie drzewa import xml doc = xml.dom.minidom.parse('content.xml')
nodetype nodename nodevalue parentnode childnodes firstchild lastchild previoussibling nextsibling attributes Klasa Node - atrybuty
Modyfikacja drzewa appendchild(newchild) removechild(oldchild) replacechild(newchild, oldchild)
Tworzenie nowych węzłów new = document.createelement('chapter') new.setattribute('number', '5') document.documentelement.appendchild(new)
Iterator po drzewie from xml.dom.nodefilter import NodeFilter reader = Sax2.Reader() doc = reader.fromstream(open('plik.xml', 'r'))
Iterator po drzewie walker = doc.createtreewalker(doc.documentelement, NodeFilter.SHOW_ALL, None, 0) while 1: print walker.currentnode.nodename next = walker.nextnode() if next is None: break
XPath Selekcja ścieżek w drzewie
Xpath - przykład from xml import xpath nodes = xpath.evaluate('ksiazka/autor', doc.documentelement)
KONIEC