Nauka wyrażeń regularnych [zamknięte]


166

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ż podać do nich link?

Odpowiedzi:


789

Najważniejszą częścią są koncepcje. Kiedy już zrozumiesz, jak działają elementy budulcowe, różnice w składni będą niewiele więcej niż łagodne dialekty. 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ć, pomoże Ci 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! (Słowo rein grepodnosi się do wyrażeń regularnych).

Zamów z menu

Dodając tylko trochę złożoności, możesz dopasować do wzorca albo „Nick”, albo „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 albo „a”, „b”, albo „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 wzoru 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 jego 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ę. Mechanizmy wyrażeń regularnych często 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ż liczenie 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).

W innym przykładzie 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ą tyle tekstu, ile mogą, jednocześnie pozwalając na pomyślne dopasowanie całego wzorca.

Na przykład, powiedzmy, że wejście 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 przełączyć się z zachłannych na ostrożne, dodaj ?do kwantyfikatora jeszcze jeden. 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 wprowadzisz „(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 ((.+?))zrobiłoby 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” z własnymi 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 w formularzu

-- This is a comment --

napisałbyś ^--\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:

Książki

Darmowe zasoby

Notatka

†: Powyższe stwierdzenie, które .pasuje do dowolnego znaku, jest uproszczeniem ze względów pedagogicznych, które nie jest do końca prawdziwe. Kropka pasuje do dowolnego znaku poza "\n"nową linią, 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 spacja lub dowolna inna spacja”, innymi słowy cokolwiek.


14
Możesz także skorzystać z metody prób i błędów, a następnie skorzystanie z internetowego testera regex i debuggera może być ogromną pomocą: regex101.com
Juraj.Lorinc

2
Warto wspomnieć, że pomimo tego, że jest podobnym wzorcem, a{,m}nie jest rzeczą, przynajmniej w Javascript, Perl i Pythonie.
Załóż pozew Moniki

2
Warto wspomnieć, że istnieją różne rodzaje silników wyrażeń regularnych, z których każdy ma inny zestaw funkcji i reguły składniowe.
hek2mgl

1
hackr.io/tutorials/learn-regular-expressions-regex to świetne miejsce, aby znaleźć najlepsze samouczki dotyczące wyrażeń regularnych online. Wszystkie tutoriale tutaj są przesyłane i polecane (tak jak SO) przez społeczność programistów.
Saurabh Hooda

2
Doceń swoje wysiłki, aby przedstawić to wszystko w pigułce.
Saurabh Tiwari
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.