Kurs języka Python

Wykład 8.

Przetwarzanie tekstu

● Wyrażenia regularne

● Biblioteka url ib

● 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.i .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 '\['

Próby rozwiązania

re.match('\[', '\[')

re.match('\\[', '\[')

re.match('\\\[', '\[')

re.match('\\\\[', '\[')

re.match('\\\\\[', '\[')

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 url ib

in_stream = url ib.urlopen('http://www.python.org') doc = f.read()

f.close()

Strumień

● in_stream.readlines()

● for line in in_stream: print line,

Parsowanie html

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

Uruchomienie

p = MyParser()

p.feed(doc)

p1.close()

XML

Extensible Markup Language

Przykład

<?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>

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')

Klasa Node - atrybuty

nodeType

nodeName

nodeValue

parentNode

childNodes

firstChild

lastChild

previousSibling

nextSibling

attributes

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