Blog JSystems - z miłości do programowania

Wyrażenia regularne



Wyrażenia regularne służą do wyszukiwania w tekście jego elementów wg. zadanych wzorców. Pozwalają na przykład odnaleźć i wyciąć wszystkie elementy pasujące do wzorca np numery telefonów czy adresy email. Zaczniemy od przykładów bardzo prostych. Wraz z kolejnymi zagadnieniami poznamy też kolejne funkcje służące do pracy z wyrażeniami regularnymi.


W pierwszych przykładach będę posługiwał się funkcją "findall" odnajdującą wszystkie wystąpienia pasujące do wzorca. Jest to po prostu najwygodniejsza funkcja na potrzeby przykładów, ale w wielu przypadkach jej zastosowanie nie będzie wydajne - czasem zechcesz np. znaleźć tylko pierwsze wystąpienie elementu w bardzo długim tekście i nie chcesz czytać i przetwarzać całości. Wszystkie funkcje które będą poruszane w ramach tego rozdziału znajdziesz w bibliotece "re" dostępnym natywnie w Pythonie.


 


Podstawowe wyszukiwanie


Poniżej bardzo naiwny przykład, ale służy zaprezentowaniu zasad działania funkcji "findall":


import re
tekst='siała baba mak i dostała 10 lat'
wzorzec='baba'
print (re.findall(wzorzec,tekst))


Wynik na konsoli:


['baba']


Pierwsza linia to oczywiście import odpowiedniej biblioteki. Zmienna "tekst" zawiera tekst w którym będziemy wyszukiwać. Zmienna "wzorzec" określa element szukany. Zwykle znajdzie się tutaj jakieś wyrażenie a nie zwyczajny ciąg tekstowy. Pod deklaracjami zmiennych drukujemy wynik działania funkcji "findall" która w postaci tablicy zwraca nam wszystkie elementy pasujące do wzorca. Jako pierwszy parametr podajemy wzorzec wyszukiwania, drugi  podajemy tekst który zamierzamy przeszukiwać. Za chwilę przedstawię symbole określające rodzaj wyszukiwanych znaków oraz symbole określające ilość wystąpień, byśmy mogli już dalej bez przeszkód zająć się wyszukiwaniem.


 


Typy znaków


Poniżej znajduje się zestawienie symboli które pozwalają nam odnajdować elementy.


\d - cyfry


\D - znaki nie będące cyfrą


\w  - alfanumeryki


\W - wszystko co nie jest alfanumerykiem


\s - białe znaki


\S - wszystko co nie jest białym znakiem


. - dowolny znak


[a-f] - małe litery z zakresu a-f


[A-F] - duże litery z zakresu A-F


[0-3] - cyfry w zakresie 0-3


[a-z0-6] - małe litery w zakresie a-z lub cyfry w zakresie 0-6


[^a-f] - wszystko co nie jest małą literą w zakresie a-f




Kwantyfikatory ilościowe


Poniżej zestawienie symboli określających krotność wystąpień poszukiwanego elementu.


- dowolna ilość znaków - w tym zero!


+ - co najmniej jedno wystąpienie, ale może być też więcej


? - zero lub jedno wystąpienie - ale nie więcej


{1,5} - od jednego do pięciu wystąpień


{5,} - co najmniej 5 wystąpień


{,5} - do 5 wystąpień


 


Wykorzystanie symboli i kwantyfikatorów do wyszukiwania elementów według wzorca


Połączmy teraz poznane symbole i kwantyfikatory ilościowe i wyszukajmy coś w tekście:


import re
tekst='Badanie statystyczne 565 dzieł sztuki różnych wielkich malarzy, przeprowadzone w 1999, wykazało, że ci artyści nie użyli złotego podziału w wymiarach swoich płócien.' \
      'Badanie stwierdziło, że średni stosunek dwóch boków badanych obrazów wynosi 1,34, ze średnimi dla poszczególnych malarzy obejmującymi od 1,04 (Goya) do 1,46 (Bellini)[35].' \
      'Z drugiej strony, Pablo Tosto wymienił ponad 350 dzieł znanych artystów, z których ponad 100 miało płótna o proporcjach złotego prostokąta i pierwiastka z 5, natomiast inne' \
      ' proporcje takie jak pierwiastki z 2, 3, 4 i 6[36]. '
wzorzec='\d'
print (re.findall(wzorzec,tekst))


Wykorzystałem symbol "\d" do wyszukania wszystkich cyfr z tekstu. Wynik na konsoli:


['5', '6', '5', '1', '9', '9', '9', '1', '3', '4', '1', '0', '4', '1', '4', '6', '3', '5', '3', '5', '0', '1', '0', '0', '5', '2', '3', '4', '6', '3', '6']


Jak widzimy każda cyfra jest jako osobny element zbioru, ponieważ szukaliśmy jednej cyfry - nie określiliśmy kwantyfikatora ilościowego. Tym razem poszukajmy liczb składających się z 3 lub 4 samych cyfr (bez przecinka rozdzielającego wartości całkowitych od dziesiętnych - liczb zawierających ułamki nie chcemy:


wzorzec='\d{3,4}'


Wynik:


['565', '1999', '350', '100']


Co tu się zadziało? We wzorcu mamy symbol "\d" oznaczający wyszukiwanie cyfr, oraz kwantyfikator ilościowy "{3,4}" określający ilość wystąpień od 3 do 4. Kwantyfikator ilościowy odnosi się do poprzedzającego elementu. Trochę trzeba się wypowiadać jak Yoda: "znajdź mi cyfry trzy lub cztery". Poszukajmy więc liczb zawierających część ułamkową. Wzorzec:


wzorzec='\d,\d{2}'


Tym razem powiedzieliśmy : "znajdź element składający się z jednej cyfry, po którym następuje przecinek, po którym następują dwie kolejne cyfry. Wynik:


['1,34', '1,04', '1,46']


Znajdźmy teraz numer telefonu:


import re
tekst='Pod tym numerem możesz zamówić kebsika: 22 299 53 69. Trzeba prosić do telefonu Panią Bożenkę. '
wz='[\d ]{9,}'
print(re.findall(wz,tekst))


Wynik:


[' 22 299 53 69']


Co oznacza wzorzec "[\d ]{9,}"? Element składający się z cyfr albo spacji o długości co najmniej 9 znaków. Może się też pojawić sytuacja w której mamy do wyszukania jakieś znaki mogące być potraktowane jako znaki specjalne np. ".". W takie sytuacji należy wyłączyć ich specjalne znaczenie za pomocą znaku "\".


 

Przyjdź do nas na szkolenie z języka Python! Mamy szereg szkoleń w ofercie, od podstawowych po aplikacje webowe z użyciem Django, analizę danych, tesowanie, machine learning i wiele innych.
Sprawdź dostępne szkolenia Python
Zapisz się do newslettera aby otrzymywać najnowsze świeżynki pojawiające się na blogu!