re – Operacje na wyrażeniach regularnychś

Składnia wyrażeń regularnychś

Wyrażenie regularne (lub RE) określa zbiór łańcuchów, które do niego pasują; funkcje w tym module pozwalają sprawdzić, czy dany łańcuch pasuje do danego wyrażenia regularnego (lub czy dane wyrażenie regularne pasuje do danego łańcucha, co sprowadza się do tego samego).

Wyrażenia regularne mogą być konkatenowane w celu utworzenia nowych wyrażeń regularnych; jeśli A i B są obydwoma wyrażeniami regularnymi, to AB jest również wyrażeniem regularnym.Ogólnie, jeśli łańcuch p pasuje do A i inny łańcuch q pasuje do B, to łańcuch pq będzie pasował do AB. Ma to miejsce, chyba że A lub B zawierają operacje o niskim priorytecie; warunki brzegowe pomiędzy A i B; lub mają numerowane odniesienia do grup. Tak więc, złożone wyrażenia mogą być łatwo skonstruowane z prostszych wyrażeń pierwotnych, takich jak te opisane tutaj. Szczegóły teorii i implementacji wyrażeń regularnych można znaleźć w książce Friedla lub w prawie każdym podręczniku o budowie kompilatorów.

Poniżej znajduje się krótkie wyjaśnienie formatu wyrażeń regularnych. Więcej informacji i łagodniejszą prezentację znajdziesz w Regular Expression HOWTO.

Wyrażenia regularne mogą zawierać zarówno znaki specjalne, jak i zwykłe. Znaki specjalne, takie jak 'A', 'a', lub '0', są najprostszymi wyrażeniami regularnymi; po prostu pasują do siebie. Można łączyć zwykłe znaki, więc last pasuje do łańcucha 'last'. (W dalszej części tego rozdziału będziemy pisać znaki RE w this special style, zwykle bez cudzysłowów, a łańcuchy, które mają być dopasowane 'in single quotes'.)

Niektóre znaki, jak '|' lub '(', są specjalne. Znaki specjalne albo oznaczają klasy zwykłych znaków, albo wpływają na sposób interpretacji wyrażeń regularnych wokół nich.

Kwalifikatory powtórzeń (*, +, ?, {m,n}, itd) nie mogą być pośrednio zagnieżdżone. Pozwala to uniknąć niejednoznaczności z nieredukowalnym sufiksem modyfikatora?, a także z innymi modyfikatorami w innych implementacjach. Aby zastosować drugie powtórzenie do powtórzenia wewnętrznego, można użyć nawiasów. Na przykład, wyrażenie (?:a{6})* dopasowuje dowolną wielokrotność sześciu znaków 'a'.

Znakami specjalnymi są:

.

(Kropka.) W trybie domyślnym, dopasowuje to dowolny znak z wyjątkiem nowej linii. Jeśli podano flagę DOTALL, pasuje to do dowolnego znaku, łącznie z nową linią.

^

(Caret.) Dopasowuje początek łańcucha, a w trybie MULTILINE także natychmiast po każdej nowej linii.

$

Dopasowuje koniec łańcucha lub tuż przed nową linią na końcu łańcucha, a w trybie MULTILINE także przed nową linią. foo dopasowuje zarówno 'foo’ jak i 'foobar’, podczas gdy wyrażenie regularne foo$ dopasowuje tylko 'foo’. Co ciekawsze, szukanie foo.$ w 'foo1\nfoo2\n' pasuje do 'foo2′ normalnie, ale do 'foo1′ w trybie MULTILINE; szukanie pojedynczego $ w 'foo\n' znajdzie dwa (puste) dopasowania: jedno tuż przed nową linią i jedno na końcu łańcucha.

*

Powoduje, że wynikowe RE pasuje do 0 lub więcej powtórzeń poprzedniego RE, tak wielu powtórzeń, jak to tylko możliwe. ab* dopasowuje 'a’, 'ab’ lub 'a’, po którym następuje dowolna liczba 'b’.

+

Powoduje, że wynikowe RE dopasowuje 1 lub więcej powtórzeń poprzedniego RE.ab+ dopasowuje 'a’, po którym następuje dowolna niezerowa liczba 'b’; nie dopasowuje tylko 'a’.

?

Powoduje, że wynikowe RE dopasowuje 0 lub 1 powtórzenie poprzedzającego RE.ab? dopasuje albo 'a’ albo 'ab’.

*?,+?,??

Kwalifikatory '*', '+' i '?' są zachłanne; dopasowują tak wiele tekstu, jak to tylko możliwe. Czasami takie zachowanie nie jest pożądane; jeśli RE<.*> jest dopasowywane do '<a> b <c>', to dopasuje cały łańcuch, a nie tylko '<a>'. Dodanie ? po kwalifikatorze powoduje, że wykona on dopasowanie w sposób nieżałosny lub minimalny; dopasowana zostanie tak mała liczba znaków, jak to tylko możliwe. Użycie RE <.*?> dopasuje tylko '<a>'.

{m}

Określa, że dokładnie m kopii poprzedniego RE powinno zostać dopasowanych; mniejsza liczba znaków powoduje, że całe RE nie zostanie dopasowane. Na przykład, a{6} dopasuje dokładnie sześć znaków 'a', ale nie pięć.

{m,n}

Powoduje, że wynikowe RE dopasuje od m do n powtórzeń poprzedniegoRE, starając się dopasować jak najwięcej powtórzeń. Na przykład, a{3,5} dopasuje od 3 do 5 znaków 'a'. Pominięcie m określa dolną granicę równą zero, a pominięcie n określa nieskończoną górną granicę. Na przykład a{4,}b będzie pasować do 'aaaab' lub tysiąca znaków 'a', po których następuje 'b', ale nie do 'aaab'. Przecinek nie może być pominięty, gdyż w przeciwnym razie modyfikator byłby mylony z poprzednio opisaną formą.

{m,n}?

Powoduje, że wynikowe RE dopasowuje od m do n powtórzeń poprzedniegoRE, starając się dopasować jak najmniej powtórzeń. Jest to wersjaon-greedy poprzedniego kwalifikatora. Na przykład, na sześcioznakowym łańcuchu 'aaaaaa', a{3,5} dopasuje 5 znaków 'a', podczas gdy a{3,5}? dopasuje tylko 3 znaki.

\

Albo wymyka znaki specjalne (pozwalając dopasować znaki takie jak '*', '?' i tak dalej), albo sygnalizuje sekwencję specjalną; sekwencje specjalne są omówione poniżej.

Jeśli nie używasz surowego łańcucha do wyrażenia wzorca, pamiętaj, że Python używa również odwrotnego ukośnika jako sekwencji ucieczki w literałach łańcuchowych; jeśli sekwencja ucieczki nie jest rozpoznawana przez parser Pythona, odwrotny ukośnik i następny znak są zawarte w wynikowym łańcuchu. Jednakże, jeśli Python rozpoznałby wynikową sekwencję, odwrotny ukośnik powinien być powtórzony dwukrotnie. Jest to skomplikowane i trudne do zrozumienia, dlatego zaleca się używanie łańcuchów znaków dla wszystkich, z wyjątkiem najprostszych wyrażeń.

Używane do wskazywania zestawu znaków. W zestawie:

  • Znaki mogą być wymienione pojedynczo, np. będzie pasować do 'a','m' lub 'k'.

  • Zakresy znaków można wskazać, podając dwa znaki i oddzielając je znakiem '-', na przykład będzie pasować do każdej małej litery ASCII, będzie pasować do wszystkich liczb dwucyfrowych od 00 do 59, a będzie pasować do każdej cyfry szesnastkowej. Jeśli - jest escape’owane (np.) lub jeśli jest umieszczone jako pierwszy lub ostatni znak (np. lub ), będzie pasować do dosłownego '-'.

  • Znaki specjalne tracą swoje specjalne znaczenie wewnątrz zestawów. Na przykład dopasuje dowolny z literalnych znaków '(', '+', '*' lub ')'.

  • Klasy znaków takie jak \w lub \S (zdefiniowane poniżej) są również akceptowane wewnątrz zestawu, chociaż znaki, do których pasują, zależą od tego, czy obowiązuje trybASCII czy LOCALE.

  • Znaki, które nie mieszczą się w zakresie, można dopasować przez uzupełnienie zestawu. Jeśli pierwszym znakiem zestawu jest '^', to dopasowane zostaną wszystkie znaki, które nie znajdują się w zestawie. Na przykład, dopasuje każdy znak z wyjątkiem '5', a dopasuje każdy znak z wyjątkiem '^'. ^ nie ma specjalnego znaczenia, jeśli nie jest pierwszym znakiem w zestawie.

  • Aby dopasować dosłowny ']' wewnątrz zestawu, należy poprzedzić go odwrotnym ukośnikiem lub umieścić na początku zestawu. Na przykład, zarówno {}] jak i() będą pasować do nawiasów.

  • Obsługa zagnieżdżonych zestawów i operacji na zestawach, jak w Unicode TechnicalStandard #18, może zostać dodana w przyszłości. To zmieniłoby składnię, więc aby ułatwić tę zmianę, na razie w niejednoznacznych przypadkach będzie podnoszony znak FutureWarning. Obejmuje to zestawy zaczynające się od literału '.

    (...)

    Pasuje do dowolnego wyrażenia regularnego wewnątrz nawiasów i wskazuje początek i koniec grupy; zawartość grupy można odzyskać po wykonaniu dopasowania i można ją dopasować w dalszej części łańcucha za pomocą sekwencji specjalnej \number, opisanej poniżej. Aby dopasować literały '(' lub ')', należy użyć \( lub \), albo zamknąć je wewnątrz klasy znaków: , .

    (?...)

    Jest to notacja rozszerzająca (znak '?' występujący po '(' nie ma znaczenia w innych przypadkach). Pierwszy znak po '?' określa, jakie jest znaczenie i dalsza składnia konstrukcji. Rozszerzenia zwykle nie tworzą nowej grupy; (?P<name>...) jest jedynym wyjątkiem od tej reguły. Poniżej są obecnie obsługiwane rozszerzenia.

    (?aiLmsux)

    (Jedna lub więcej liter z zestawu 'a', 'i', 'L', 'm','s', 'u', 'x'). Grupa pasuje do pustego łańcucha; litery ustawiają odpowiednie flagi: re.A (dopasowywanie tylko ASCII),re.I (ignoruj wielkość liter), re.L (zależne od locale),re.M (wieloliniowe), re.S (kropka dopasowuje wszystko),re.U (dopasowywanie Unicode), i re.X (verbose), dla całego wyrażenia regularnego.(Flagi są opisane w Module Contents.)Jest to przydatne, jeśli chcesz dołączyć flagi jako część wyrażenia regularnego, zamiast przekazywać argument flagi do funkcjire.compile(). Flagi powinny być używane jako pierwsze w łańcuchu wyrażenia.

    (?:...)

    Nie przechwytująca wersja nawiasów regularnych. Dopasowuje dowolne wyrażenie regularne znajdujące się wewnątrz nawiasów, ale podłańcuch dopasowany przez grupę nie może być odzyskany po wykonaniu dopasowania lub przywołany w dalszej części wzorca.

    (?aiLmsux-imsx:...)

    (zero lub więcej liter z zestawu 'a', 'i', 'L', 'm','s', 'u', 'x', opcjonalnie z '-', po którym następuje jedna lub więcej liter z zestawu 'i', 'm', 's', 'x'.)Litery te ustawiają lub usuwają odpowiednie flagi:re.A (dopasowywanie tylko ASCII), re.I (ignoruj wielkość liter),re.L (zależne od locale), re.M (wielowierszowe),re.S (kropka dopasowuje wszystko), re.U (dopasowywanie Unicode) i re.X (verbose), dla części wyrażenia.(Flagi są opisane w Module Contents.)

    Literki 'a', 'L' i 'u' wykluczają się wzajemnie, gdy są używane jako flagi inline, więc nie mogą być łączone ani występować po '-'. Zamiast tego, gdy jedna z nich pojawia się w grupie inline, nadpisuje tryb dopasowania w grupie zamykającej. We wzorcach Unicode (?a:...) przełącza na dopasowywanie tylko ASCII, a (?u:...) przełącza na dopasowywanie Unicode (domyślnie). We wzorcach bajtowych (?L:...) przełącza na dopasowywanie zależne od locale, a (?a:...) przełącza na dopasowywanie tylko ASCII (domyślnie).To zastąpienie działa tylko dla wąskiej grupy inline, a oryginalny tryb dopasowania jest przywracany poza grupą.

    Nowość w wersji 3.6.

    Zmienione w wersji 3.7: Litery 'a', 'L' i 'u' również mogą być używane w grupie.

    (?P<name>...)

    Podobne do zwykłych nawiasów, ale podłańcuch dopasowany przez grupę jest dostępny poprzez symboliczną nazwę grupy. Nazwy grup muszą być poprawnymi identyfikatorami Pythona, a każda nazwa grupy może być zdefiniowana tylko raz w wyrażeniu regularnym. Grupa symboliczna jest również grupą numerowaną, tak jakby nie miała nazwy.

    Do grup nazwanych można się odwoływać w trzech kontekstach. Jeśli wzorzec jest(?P<quote>).*?(?P=quote) (tj. dopasowanie do łańcucha cytowanego z pojedynczym lub podwójnym cudzysłowem):

    Kontekst odwołania do grupy „quote”

    Sposoby odwołania do niej

    w samym wzorcu

      .

    • (?P=quote) (jak pokazano)

    przy przetwarzaniu obiektu dopasowania m

    • m.group('quote')

    • m.end('quote') (itd.)

    w łańcuchu przekazywanym do repargumentu re.sub()

    • \g<quote>

    • .

    • \g<1>

    (?P=name)

    Odniesienie wsteczne do nazwanej grupy; dopasowuje tekst, który został dopasowany przez wcześniejszą grupę o nazwie nazwa.

    (?#...)

    Komentarz; zawartość nawiasów jest po prostu ignorowana.

    (?=...)

    Dopasowuje, jeśli ... dopasowuje następny, ale nie zużywa żadnego z łańcuchów. Nazywa się to asercją lookahead. Na przykład, Isaac (?=Asimov) będzie pasować do'Isaac ' tylko jeśli następuje po nim 'Asimov'.

    (?!...)

    Dopasowuje jeśli ... nie pasuje do następnego. Jest to negatywna asercja lookahead.Na przykład, Isaac (?!Asimov) dopasuje 'Isaac ' tylko jeśli nie następuje po nim 'Asimov'.

    (?<=...)

    Dopasowuje, jeśli bieżąca pozycja w łańcuchu jest poprzedzona dopasowaniem dla ..., które kończy się na bieżącej pozycji. Jest to nazywane pozytywnym lookbehindassertion. (?<=abc)def znajdzie dopasowanie w 'abcdef', ponieważlookbehind cofnie się o 3 znaki i sprawdzi, czy zawarty wzorzec pasuje. Zawarty wzorzec musi pasować tylko do łańcuchów o pewnej stałej długości, co oznacza, żeabc lub a|b są dozwolone, ale a* i a{3,4} nie. Zauważ, że wzorce, które zaczynają się od pozytywnych twierdzeń lookbehind nie będą pasować na początku szukanego łańcucha; najprawdopodobniej będziesz chciał użyć funkcjisearch() zamiast funkcji match():

    >>> import re>>> m = re.search('(?<=abc)def', 'abcdef')>>> m.group(0)'def'

    Ten przykład szuka słowa po myślniku:

    >>> m = re.search(r'(?<=-)\w+', 'spam-egg')>>> m.group(0)'egg'

    Zmienione w wersji 3.5: Dodano wsparcie dla odwołań grupowych o stałej długości.

    (?<!...)

    Dopasowuje, jeśli bieżąca pozycja w łańcuchu nie jest poprzedzona dopasowaniem dla.... Jest to nazywane negatywną asercją lookbehind. Podobnie do pozytywnych asercji lookbehind, zawarty wzorzec musi pasować tylko do łańcuchów o pewnej ustalonej długości. Wzorce, które zaczynają się od negatywnej asercji lookbehind mogą pasować na początku szukanego łańcucha.

    (?(id/name)yes-pattern|no-pattern)

    Próbuje dopasować się do yes-pattern jeśli grupa o podanym id lub nazwie istnieje, a do no-pattern jeśli nie. no-pattern jest opcjonalne i można je pominąć. Na przykład, (<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$) jest słabym wzorcem dopasowywania wiadomości e-mail, który dopasuje się do '<[email protected]>', jak również do '[email protected]', ale nie do '<[email protected]' ani '[email protected]>'.

    Sekwencje specjalne składają się z '\' i znaku z poniższej listy.Jeśli zwykły znak nie jest cyfrą lub literą ASCII, to wynikowe RE dopasuje drugi znak. Na przykład, $ pasuje do znaku '$'.

    \number

    Pasuje do zawartości grupy o tym samym numerze. Grupy są numerowane począwszy od 1. Na przykład (.+) pasuje do 'the the' lub '55 55', ale nie do 'thethe' (zwróć uwagę na spację po grupie). Ta specjalna sekwencja może być użyta tylko do dopasowania jednej z pierwszych 99 grup. Jeśli pierwszą cyfrą liczby jest 0, lub liczba ma długość 3 cyfr ósemkowych, to nie będzie interpretowana jako dopasowanie do grupy, lecz jako znak o wartości ósemkowej liczby. Wewnątrz'' klasy znaków, wszystkie ucieczki numeryczne są traktowane jak znaki.

    \A

    Pasuje tylko na początku łańcucha.

    \b

    Pasuje do pustego łańcucha, ale tylko na początku lub końcu słowa.Słowo jest zdefiniowane jako sekwencja znaków słownych. Zauważ, że formalnie, \b jest zdefiniowane jako granica między znakiem \w a \W (lub odwrotnie), lub między \w a początkiem/końcem łańcucha.Oznacza to, że r'\bfoo\b' pasuje do 'foo', 'foo.', '(foo)','bar foo baz', ale nie do 'foobar' lub 'foo3'.

    Domyślnie alfanumeryczne znaki Unicode są takie same jak te używane we wzorcach Unicode, ale można to zmienić za pomocą flagi ASCII. Granice słów są określane przez bieżące locale, jeśli użyto flagi LOCALE.Wewnątrz zakresu znaków, \b reprezentuje znak backspace, dla kompatybilności z literałami łańcuchowymi Pythona.

    \B

    Dopasowuje pusty łańcuch, ale tylko wtedy, gdy nie znajduje się on na początku lub końcu słowa. Oznacza to, że r'py\B' pasuje do 'python', 'py3', 'py2', ale nie do 'py', 'py.' lub 'py!'. \B jest przeciwieństwem \b, więc znaki słów we wzorcach Unicod są alfanumeryczne Unicode lub podkreślenie, chociaż można to zmienić za pomocą flagi ASCII. Granice słów są określane przez bieżące locale, jeśli użyto flagi LOCALE.

    \d Dla wzorców Unicode (str):

    Dopasowuje dowolną cyfrę dziesiętną Unicode (to jest dowolny znak w kategorii znakówUnicode ). Obejmuje to , a także wiele innych znaków cyfrowych. Jeśli użyta jest flaga ASCII, dopasowywany jest tylko .

    Dla wzorców 8-bitowych (bajtów):

    Dopasowuje dowolną cyfrę dziesiętną; jest to odpowiednik .

    \D

    Dopasowuje dowolny znak, który nie jest cyfrą dziesiętną. Jest to przeciwieństwo \d. Jeśli użyta jest flaga ASCII, staje się to odpowiednikiem .

    \s Dla wzorców Unicode (str):

    Sprawdza znaki białych spacji Unicode (co obejmuje, a także wiele innych znaków, na przykład spacje łamane nakazane przez zasady typografii w wielu językach). Jeśli użyta jest flaga ASCII, dopasowywane są tylko.

    Dla wzorców 8-bitowych (bajtów):

    Dopasowuje znaki uważane za białe spacje w zestawie znaków ASCII; jest to odpowiednik .

    \S

    Dopasowuje dowolny znak, który nie jest znakiem białej spacji. Jest to przeciwieństwo \s. Jeśli użyta jest flaga ASCII, staje się to odpowiednikiem .

    \w Dla wzorców Unicode (str):

    Dopasowuje znaki słów Unicode; obejmuje to większość znaków, które mogą być częścią słowa w dowolnym języku, a także liczby i podkreślenia. Jeśli użyta jest flaga ASCII, dopasowywany jest tylko.

    Dla wzorców 8-bitowych (bajtów):

    Dopasowuje znaki uważane za alfanumeryczne w zestawie znaków ASCII; jest to odpowiednik . Jeśli użyto flagi LOCALE, pasuje do znaków uznawanych za alfanumeryczne w bieżącym locale oraz do podkreślenia.

    \W

    Dopasowuje dowolny znak, który nie jest znakiem słownym. Jest to przeciwieństwo \w. Jeśli użyta jest flaga ASCII, staje się to odpowiednikiem . Jeśli użyto flagi LOCALE, dopasowuje znaki, które nie są ani alfanumeryczne w bieżącym kodzie lokalnym, ani podkreśleniem.

    \Z

    Dopasowuje tylko na końcu łańcucha.

    Większość standardowych ucieczek obsługiwanych przez literały łańcuchowe Pythona jest również akceptowana przez parser wyrażeń regularnych:

    \a \b \f \n\N \r \t \u\U \v \x \

    (Zauważ, że \b jest używany do reprezentowania granic słów i oznacza „backspace” tylko wewnątrz klas znaków.)

    '\u', '\U' i '\N' sekwencje specjalne są rozpoznawane tylko we wzorcach Unicod. We wzorcach bajtowych są one błędami. Nieznane sekwencje ucieczki z liter ASCII są zarezerwowane do przyszłego użytku i traktowane jako błędy.

    Sekwencje ucieczki z ósemek są uwzględnione w ograniczonej formie. Jeśli pierwszą cyfrą jest 0, lub jeśli są trzy cyfry ósemkowe, to jest to traktowane jako ucieczka ósemkowa. W przeciwnym razie, jest to odwołanie do grupy. Podobnie jak w przypadku literałów łańcuchowych, ucieczki ósemkowe mają zawsze co najwyżej trzy cyfry długości.

    Zmienione w wersji 3.3: Dodano sekwencje ucieczki '\u' i '\U'.

    Zmienione w wersji 3.6: Nieznane ucieczki składające się z '\' i litery ASCII są teraz błędami.

    Zmienione w wersji 3.8: Dodano sekwencję ucieczki '\N{name}'. Podobnie jak w literałach łańcuchowych, jest ona interpretowana jako nazwany znak Unicode (np. '\N{EM DASH}').

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.