Blog JSystems - uwalniamy wiedzę!

Szukaj
Wyrażenie regularne - anatomia wzorca
Regex to przepis na dopasowanie tekstu: co, ile razy i w jakiej kolejności

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 "\".

Szkolenie Python od podstaw, przez analizę danych, do machine learning w JSystems

Ten kurs daje Ci solidne podstawy Pythona. Jeśli chcesz pójść dalej i pod okiem trenera dojść od pierwszej linijki kodu do własnego modelu uczenia maszynowego, sprawdź nasze pięciodniowe szkolenie Python od podstaw, przez analizę danych, do machine learning. Pierwsze trzy dni to Python w praktyce: typy i kolekcje, instrukcje warunkowe i pętle, funkcje, moduły i pakiety, pliki tekstowe, usługi sieciowe oraz praca z bazą PostgreSQL. Czwarty dzień to analiza danych w pandas (wczytywanie CSV, TSV i XLS, filtrowanie, agregacje, statystyki) i wizualizacja w Matplotlib, Seaborn oraz Plotly. Piąty dzień to uczenie maszynowe w scikit-learn: regresja liniowa i logistyczna, drzewa decyzyjne, las losowy, XGBoost, walidacja predykcji, dobór hiperparametrów i przeciwdziałanie przeuczeniu. Szkolenie ma terminy gwarantowane, czyli odbywa się niezależnie od wielkości grupy.

Szkolenie Python od podstaw, przez analizę danych, do machine learning

To szkolenie może być dofinansowane dla Ciebie z KFS lub BUR.

★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Najczęściej zadawane pytania

Do czego służą wyrażenia regularne?
Wyrażenia regularne służą do wyszukiwania w tekście elementów pasujących do zadanych wzorców. Pozwalają na przykład odnaleźć i wyciąć wszystkie fragmenty spełniające dany wzorzec, takie jak numery telefonów czy adresy e-mail. W Pythonie funkcje do pracy z nimi znajdziesz w bibliotece re.
Co zwraca funkcja findall?
Funkcja findall odnajduje wszystkie wystąpienia pasujące do wzorca i zwraca je w postaci listy. Jest wygodna do przykładów, ale nie zawsze wydajna, bo przetwarza cały tekst. Gdy potrzebujesz tylko pierwszego wystąpienia w długim tekście, lepsze bywają inne funkcje z biblioteki re.
Czym różnią się symbole typów znaków od kwantyfikatorów?
Symbole typów znaków, na przykład oznaczenie cyfry, białego znaku czy zakresu liter, określają, czego szukasz. Kwantyfikatory ilościowe określają, ile razy dany element ma wystąpić, na przykład dowolną liczbę razy, co najmniej raz albo w podanym przedziale liczby wystąpień.
Do czego odnosi się kwantyfikator ilościowy we wzorcu?
Kwantyfikator ilościowy odnosi się do bezpośrednio poprzedzającego go elementu. Na przykład wzorzec szukający cyfry z kwantyfikatorem od trzech do czterech oznacza liczbę złożoną z trzech lub czterech cyfr. Autor porównuje to do mówienia jak Yoda: znajdź mi cyfry trzy lub cztery.
Jak wyszukać znak, który ma specjalne znaczenie w wyrażeniach regularnych?
Gdy chcesz odnaleźć znak traktowany normalnie jako specjalny, na przykład kropkę, musisz wyłączyć jego specjalne znaczenie, poprzedzając go ukośnikiem wstecznym. Dzięki temu wyrażenie regularne potraktuje taki znak dosłownie, a nie jako element składni wzorca.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...