Zanurkuj w Pythonie/Rozwlekłe wyrażenia regularne: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
zamiana {{Nawigacja|Python|->{{Nawigacja|Zanurkuj w Pythonie| [[Python/->[[../
Piotr (dyskusja | edycje)
poprawki
Linia 1:
{{Podświetl|py}}
== Rozwlekłe wyrażenia regularne ==
 
Jak na razie mieliśmy do czynienia z czymś co nazywam "kompaktowymizwięzłymi" wyrażeniami regularnymi. Jak widziałeśpewnie zauważyliśmy, są one trudne do odczytania i nawet, jeśli już je rozszyfrujeszrozszyfrujemy, nie ma gwarancji, że zrobiszzrobimy to za np. sześć miesięcy. To czego potrzebujemy, to dokumentacja w ich treści.
 
Python pozwala na to przez tworzenie tzw. ''rozwlekłych wyrażeń regularnych'' (ang. ''verbose regular expressions''). Różnią się one od kompaktowychzwięzłych dwoma rzeczami:
* Białe znaki są ignorowane. Spacje, znaki tabulacji, znaki nowej linii nie są dopasowywane jako spacje, znaki tabulacji anilub znaki nowej linii. NieZnaki te niewcalew ogóle dopasowywane. (Jeśli byśbyśmy chciałchcieli jednak dopasować któryś z nich, musisz poprzedzić je backslashemodwrotnym ukośnikiem (<tt>\</tt>).)
* Komentarze są ignorowane. Komentarz w rozwlekłym wyrażeniu regularnym wygląda dokładnie tak samo, jak w kodzie Pythona: zaczyna się od <tt>#</tt> i leci aż do końca linii. W tym przypadku jest to komentarz w wieloliniowym łańcuchu znaków, a nie w kodzie źródłowym, ale zasada działania jest taka sama.
 
Łatwiej będzie to zrozumieć jeśli skorzystamy z przykładu. WeźmySkorzystajmy kompaktoweze wyrażeniezwięzłego regularnewyrażenia jakieregularnego, tworzyliśmyktóre utworzyliśmy wcześniej i zmieńmyzróbmy jez wniego rozwlekłe. Ten przykład pokazuje jak.
 
'''{{Python/Przykład
|7.9. |Wyrażenia regularne z komentarzami'''
|tekst=
 
>>> <nowiki>pattern = """
^ # początek łańcucha znaków
M{0,43} # tysiące - 0 do 43 M
(CM|CD|D?C{0,3}) # setki - 900 (CM), 400 (CD), 0-300 (0 do 3 C),
# lub 500-800 (D, a po nim 0 do 3 C)
(XC|XL|L?X{0,3}) # dziesiątki - 90 (XC), 40 (XL), 0-30 (0 do 3 X),
# or 50-80 (L, a po nim 0 do 3 X)
(IX|IV|V?I{0,3}) # jedności - 9 (IX), 4 (IV), 0-3 (0 do 3 I),
# lub 5-8 (V, a po nim 0 do 3 I)
$ # koniec łańcucha znaków
"""</nowiki>
>>> re.search(pattern, 'M', re.VERBOSE) #(1)
{{samp|<_sre.SRE_Match object at 0x008EEB48>}}
>>> re.search(pattern, 'MCMLXXXIX', re.VERBOSE) #(2)
{{samp|<_sre.SRE_Match object at 0x008EEB48>}}
>>> re.search(pattern, 'MMMMDCCCLXXXVIIIMMMDCCCLXXXVIII', re.VERBOSE) #(3)
{{samp|<_sre.SRE_Match object at 0x008EEB48>}}
>>> re.search(pattern, 'M') #(4)
 
# Najważniejszą rzeczą o której należy pamiętać, przygdy korzystaniukorzystamy z rozwlekłych wyrażeń regularnych jest to, że musiszmusimy przekazać dodatkowy argument: <code>re.VERBOSE</code>. Jest to stała zdefiniowana w module <code>re</code>, która sygnalizuje, że wyrażenie powinno być traktowane jako rozwlekłe. Jak widziszwidzimy, ten wzorzec ma mnóstwo białych znaków (które są ignorowane) i kilka komentarzy (które też są ignorowane). Gdy zignorujesz iusuniemy białe znaki i komentarze, to pozostanie dokładnie to samo wyrażenie regularne, jakie otrzymaliśmy w poprzednim przykładzie, ale o wiele bardziej czytelne. (Zauważmy, że co prawda łańcuch znaków posiada polskie znaki, ale nie tworzymy go w unikodzie, ponieważ i tak te znaki nie mają dla nas żadnego znaczenia, ponieważ są w komentarzach.)
# To dopasowuje początek łańcucha, potem jedno z czterechtrzech możliwych <tt>M</tt>, potem <tt>CM</tt>, <tt>L</tt> i trzy z trzech możliwych <tt>X</tt>, potema następnie <tt>IX</tt> i koniec łańcucha.
# To dopasowuje początek łańcucha, potem czterytrzy z czterechtrzech możliwych <tt>M</tt>, dalej <tt>D</tt>, trzy z trzech możliwych <tt>C</tt>, <tt>L</tt> z trzema możliwymi <tt>X</tt>, potem <tt>V</tt> z trzema możliwymi <tt>I</tt> i na koniec koniec łańcucha.
# Tutaj nie udało się dopasować niczego. Czemu? Ponieważ nie przekazaliśmy flagi <code>re.VERBOSE</code>, więc funkcja <code>re.search</code> traktuje to wyrażenie regularne jako kompaktowezwięzłe, z dużą ilością białych znaków i hash'ówkratek. Python nie rozpoznaje samodzielnie, czy każemy mu dopasować kompaktowezwięzłe, czy może rozwlekłe wyrażenie regularne i przyjmuje, że każde jest kompaktowezwięzłe, chyba że wyraźnie wskażemy, że tak nie jest.
 
<noinclude>
{{Nawigacja|Zanurkuj w Pythonie|
[[../Składnia ?n, m?|Składnia <tt>{n,m}</tt>]]|
[[../Analiza przypadku: Przetwarzanie numerów telefonów|Analiza przypadku: Przetwarzanie numerów telefonów/]]|
}}
{{Podświetl|py}}
</noinclude>