Nauka wyrażeń regularnych [zamknięte]

Aug 07 2008

Naprawdę nie rozumiem wyrażeń regularnych. Czy możesz mi je wyjaśnić w łatwy do zrozumienia sposób? Jeśli są jakieś narzędzia lub książki online, czy możesz również zamieścić do nich link?

Odpowiedzi

802 GregBacon May 03 2010 at 23:09

Najważniejszą częścią są koncepcje. Kiedy zrozumiesz, jak działają te elementy, różnice w składni sprowadzą się do niewiele więcej niż łagodnych dialektów. Warstwa nad składnią silnika wyrażeń regularnych to składnia używanego języka programowania. Języki, takie jak Perl, eliminują większość tej komplikacji, ale będziesz musiał pamiętać o innych kwestiach, jeśli używasz wyrażeń regularnych w programie C.

Jeśli myślisz o wyrażeniach regularnych jako elementach budulcowych, które możesz dowolnie mieszać i dopasowywać, pomaga to nauczyć się pisać i debugować własne wzorce, ale także rozumieć wzorce napisane przez innych.

Zacznij prosto

Koncepcyjnie najprostsze wyrażenia regularne to znaki dosłowne. Wzorzec Npasuje do znaku „N”.

Wyrażenia regularne obok siebie dopasowują sekwencje. Na przykład wzorzec Nickdopasowuje sekwencję „N”, po której następuje „i”, po którym następuje „c”, a następnie „k”.

Jeśli kiedykolwiek używałeś grepw Uniksie - nawet jeśli tylko szukałeś zwyczajnie wyglądających łańcuchów - już używałeś wyrażeń regularnych! (Termin rein grepodnosi się do wyrażeń regularnych).

Zamów z menu

Dodając tylko trochę złożoności, możesz dopasować do wzorca „Nick” lub „nick” [Nn]ick. Część w nawiasach kwadratowych jest klasą znaków , co oznacza, że ​​pasuje dokładnie do jednego z zawartych w niej znaków. Możesz także używać zakresów w klasach znaków, więc [a-c]dopasowuje „a”, „b” lub „c”.

Wzorzec .jest wyjątkowy: zamiast dopasowywać tylko literalną kropkę, dopasowuje dowolny znak . Koncepcyjnie jest taki sam, jak naprawdę duża klasa postaci [-.?+%$A-Za-z0-9...].

Pomyśl o klasach postaci jak o menu: wybierz tylko jedną.

Pomocne skróty

Używanie .może zaoszczędzić wiele pisania, a istnieją inne skróty do typowych wzorców. Powiedzmy, że chcesz dopasować cyfrę: to jeden ze sposobów zapisu [0-9]. Cyfry są częstym celem dopasowania, więc możesz zamiast tego użyć skrótu \d. Inne to \s(białe spacje) i \w(znaki słowne: znaki alfanumeryczne lub podkreślenia).

Warianty pisane wielkimi literami są ich uzupełnieniami, więc \Sdopasowuje na przykład dowolny znak niebędący białą spacją.

Raz to za mało

Stamtąd możesz powtórzyć części swojego wzorca za pomocą kwantyfikatorów . Na przykład wzorzec ab?cdopasowuje „abc” lub „ac”, ponieważ ?kwantyfikator sprawia, że ​​podwzór, który modyfikuje, jest opcjonalny. Inne kwantyfikatory to

  • * (zero lub więcej razy)
  • + (raz lub więcej razy)
  • {n}(dokładnie n razy)
  • {n,}(co najmniej n razy)
  • {n,m}(co najmniej n razy, ale nie więcej niż m razy)

Łącząc ze sobą niektóre z tych bloków, wzór [Nn]*ickpasuje do wszystkich

  • ick
  • Nacięcie
  • nacięcie
  • Nnick
  • nick
  • nnick
  • (i tak dalej)

Pierwszy mecz to ważna lekcja: *zawsze się udaje! Każdy wzorzec może pasować zero razy.

Kilka innych przydatnych przykładów:

  • [0-9]+(i jej odpowiednik \d+) pasuje do dowolnej nieujemnej liczby całkowitej
  • \d{4}-\d{2}-\d{2} pasuje do dat w formacie 01.01.2019

Grupowanie

Kwantyfikator modyfikuje wzorzec znajdujący się bezpośrednio po lewej stronie. Możesz spodziewać 0abc+0się dopasowania „0abc0”, „0abcabc0” itd., Ale wzorzec bezpośrednio po lewej stronie kwantyfikatora plus to c. Oznacza to, że 0abc+0dopasowuje „0abc0”, „0abcc0”, „0abccc0” i tak dalej.

Aby dopasować jedną lub więcej sekwencji „abc” z zerami na końcach, użyj 0(abc)+0. Nawiasy oznaczają wzór podrzędny, który można określić ilościowo jako jednostkę. Często też silniki wyrażeń regularnych zapisują lub „przechwytują” część tekstu wejściowego, która pasuje do grupy umieszczonej w nawiasach. Wyodrębnianie bitów w ten sposób jest znacznie bardziej elastyczne i mniej podatne na błędy niż zliczanie indeksów i substr.

Alternacja

Wcześniej widzieliśmy jeden sposób dopasowania „Nick” lub „nick”. Inny jest z naprzemiennością jak w Nick|nick. Pamiętaj, że przemienność obejmuje wszystko po lewej stronie i wszystko po prawej stronie. Użyj grupowanie nawiasów w celu ograniczenia zakresu |, na przykład , (Nick|nick).

Na przykład, można by równoważnie napisać [a-c]jako a|b|c, ale prawdopodobnie będzie to nieoptymalne, ponieważ wiele implementacji zakłada, że ​​alternatywy będą miały długości większe niż 1.

Ucieczka

Chociaż niektóre postacie pasują do siebie, inne mają specjalne znaczenie. Wzorzec \d+nie pasuje do ukośnika odwrotnego, po którym następuje mała litera D, po której następuje znak plus: aby to uzyskać, użylibyśmy \\d\+. Ukośnik odwrotny usuwa specjalne znaczenie z następującego znaku.

Łakomstwo

Kwantyfikatory wyrażeń regularnych są chciwe. Oznacza to, że dopasowują jak najwięcej tekstu, jednocześnie pozwalając na pomyślne dopasowanie całego wzorca.

Na przykład, powiedzmy, że dane wejściowe to

„Cześć”, powiedziała, „Jak się masz?”

Możesz spodziewać ".+"się dopasowania tylko do „Hello”, a wtedy będziesz zaskoczony, gdy zobaczysz, że pasuje od „Hello” aż do „you?”.

Aby przejść z zachłannego do tego, co możesz uważać za ostrożne, dodaj dodatkowe ?do kwantyfikatora. Teraz rozumiesz, jak \((.+?)\)działa przykład z twojego pytania. Dopasowuje sekwencję dosłownego lewego nawiasu, po którym następuje jeden lub więcej znaków i kończy się prawym nawiasem.

Jeśli dane wejściowe to „(123) (456)”, pierwsze przechwycenie będzie miało wartość „123”. Niechciane kwantyfikatory chcą, aby reszta wzorca zaczęła dopasowywać się tak szybko, jak to możliwe.

(Co do twojego pomieszania, nie znam żadnego dialektu wyrażeń regularnych, w którym można ((.+?))by zrobić to samo. Podejrzewam, że gdzieś po drodze coś zgubiło się podczas transmisji.)

Kotwice

Użyj specjalnego wzorca, ^aby dopasować tylko na początku wprowadzania i $dopasować tylko na końcu. Wykonywanie „podpórek” ze swoimi wzorami, w których mówisz: „Wiem, co jest z przodu iz tyłu, ale daj mi wszystko pomiędzy” jest przydatną techniką.

Powiedz, że chcesz dopasować komentarze do formularza

-- This is a comment --

ty byś pisał ^--\s+(.+)\s+--$.

Zbuduj swoją własną

Wyrażenia regularne są rekurencyjne, więc teraz, gdy rozumiesz te podstawowe zasady, możesz je łączyć w dowolny sposób.

Narzędzia do pisania i debugowania wyrażeń regularnych:

  • RegExr (dla JavaScript)
  • Perl: YAPE: Regex Explain
  • Regex Coach (silnik wspierany przez CL-PPCRE )
  • RegexPal (dla JavaScript)
  • Tester online wyrażeń regularnych
  • Regex Buddy
  • Regex 101 (dla PCRE, JavaScript, Python, Golang)
  • Visual RegExp
  • Expresso (dla .NET)
  • Rubular (dla Ruby)
  • Biblioteka wyrażeń regularnych (wstępnie zdefiniowane wyrażenia regularne dla typowych scenariuszy)
  • Txt2RE
  • Regex Tester (dla JavaScript)
  • Regex Storm (dla .NET)
  • Debuggex (wizualny tester i pomocnik wyrażeń regularnych)

Książki

  • Opanowanie wyrażeń regularnych , wydanie drugie i trzecie .
  • Ściągawka dotycząca wyrażeń regularnych
  • Książka kucharska Regex
  • Naucz się wyrażeń regularnych

Darmowe zasoby

  • RegexOne - ucz się za pomocą prostych, interaktywnych ćwiczeń.
  • Wyrażenia regularne - wszystko, co powinieneś wiedzieć (seria PDF)
  • Podsumowanie składni wyrażeń regularnych
  • Jak działa Regexes

Notatka

†: Powyższe stwierdzenie, które .pasuje do dowolnego znaku, jest uproszczeniem ze względów pedagogicznych, które nie jest do końca prawdą. Kropka pasuje do dowolnego znaku z wyjątkiem nowej linii, "\n"ale w praktyce rzadko spodziewasz się, że wzorzec, na przykład .+przekroczy granicę nowej linii. Na przykład wyrażenia regularne Perla mają /sprzełącznik i Javę Pattern.DOTALL, aby w .ogóle dopasować dowolny znak. W przypadku języków, które nie mają takiej funkcji, możesz użyć czegoś takiego, jak [\s\S]„dowolna biała spacja lub dowolna inna niż biała spacja”, innymi słowy, cokolwiek.