JavaRush /Blog Java /Random-PL /RegEx: 20 krótkich kroków do opanowania wyrażeń regularny...
Artur
Poziom 40
Tallinn

RegEx: 20 krótkich kroków do opanowania wyrażeń regularnych. Część 2

Opublikowano w grupie Random-PL
RegEx: 20 krótkich kroków do opanowania wyrażeń regularnych. Część 1 Oryginał tutaj W ostatniej części opanowaliśmy najprostsze wyrażenia regularne i już się czegoś nauczyliśmy. W tej części przyjrzymy się nieco bardziej skomplikowanym projektom, ale uwierz mi, nie będzie to tak trudne, jak mogłoby się wydawać. RegEx: 20 krótkich kroków do opanowania wyrażeń regularnych.  Część 2 - 1Więc kontynuujmy!

Krok 8: Gwiazda *i znak plus+

RegEx: 20 krótkich kroków do opanowania wyrażeń regularnych.  Część 2 - 2Do tej pory udało nam się mniej więcej dopasować tylko ciągi o określonej długości. Jednak w przypadku najnowszych problemów dotarliśmy do granicy tego, co możemy zrobić z notacją, którą widzieliśmy do tej pory. Załóżmy na przykład, że nie jesteśmy ograniczeni do 3-znakowych identyfikatorów Java, ale możemy mieć identyfikatory o dowolnej długości. Rozwiązanie, które mogło zadziałać w poprzednim przykładzie, nie będzie działać w następującym przykładzie:
wzór: [a-zA-Z_$]\w\w 
ciąg:   __e $12 3 3.2 fo Bar r a23 mm ab x
mecze: ^^^ ^^^ ^^^ ^^^  
( Przykład ) notatkaże jeśli identyfikator jest ważny, ale dłuższy niż 3 znaki, dopasowywane są tylko pierwsze trzy znaki. A gdy identyfikator jest prawidłowy, ale zawiera mniej niż 3 znaki, to wyrażenie regularne w ogóle go nie znajdzie! Problem polega na tym, że wyrażenia w nawiasach []dopasowują dokładnie jeden znak, podobnie jak klasy znaków, takie jak \w. Oznacza to, że wszelkie dopasowania w powyższym wyrażeniu regularnym muszą mieć długość dokładnie trzech znaków. Nie działa więc tak dobrze, jak byśmy sobie tego życzyli. *Znaki specjalne i mogą tu pomóc +. Są to modyfikatory, które można dodać po prawej stronie dowolnego wyrażenia, aby dopasować je więcej niż raz. Gwiazdka Kleene (lub „gwiazdka”) *wskazuje, że poprzedni token musi zostać dopasowany dowolną liczbę razy, włączając zero razy. Znak plus +wskazuje, że należy przeszukać jeden lub więcej razy. Zatem wyrażenie poprzedzające +jest obowiązkowe (przynajmniej raz), natomiast wyrażenie poprzedzające *jest opcjonalne, ale gdy się pojawi, może wystąpić dowolną liczbę razy. Teraz, mając tę ​​wiedzę, możemy poprawić powyższe wyrażenie regularne:
wzór: [a-zA-Z_$]\w* 
string:   __e $123 3.2 dla Barr a23mm ab x 
dopasowania: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ ^ 
( Przykład ) Teraz dopasowujemy prawidłowe identyfikatory o dowolnej długości! Bingo! Ale co by się stało, gdybyśmy użyli ? +zamiast *?
wzór: [a-zA-Z_$]\w+ 
ciąg:   __e $123 3,2 dla Barr a23mm ab x
mecze: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ 
( Przykład ) Przegapiliśmy ostatni mecz, х. Dzieje się tak, ponieważ +do dopasowania wymagany jest co najmniej jeden znak, ale ponieważ []poprzedzające je wyrażenie w nawiasach \w+„zjadło” już znak x, nie ma już dostępnych znaków, więc dopasowanie nie powiedzie się. Kiedy możemy skorzystać +? Kiedy musimy znaleźć przynajmniej jedno dopasowanie, ale nie ma znaczenia, ile razy dane wyrażenie musi pasować. Na przykład, jeśli chcemy znaleźć liczby zawierające kropkę dziesiętną:
wzór: \d*\.\d+ 
ciąg:   0,011 ,2 42 2,0 3,33 4,000 5 6 7,89012 
dopasowania: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
( Przykład ) notatkaże czyniąc liczby po lewej stronie przecinka dziesiętnego opcjonalnymi, udało nam się znaleźć zarówno 0,011, jak i 0,2. Aby to zrobić, musieliśmy dopasować dokładnie jedną cyfrę dziesiętną za pomocą \.i co najmniej jedną cyfrę po prawej stronie przecinka dziesiętnego za pomocą \d+. Powyższe wyrażenie regularne nie będzie pasować do liczby takiej jak 3., ponieważ do dopasowania potrzebna jest co najmniej jedna cyfra po przecinku dziesiętnym.

Jak zwykle rozwiążmy kilka prostych problemów:

Znajdź wszystkie angielskie słowa w poniższym fragmencie.
wzór:
ciąg znaków: 3 plus 3 to sześć, ale 4 plus trzy to 7
mecze:    ^^^^ ^^ ^^^ ^^^ ^^^^ ^^^^^ ^^ 
( Rozwiązanie ) Znajdź wszystkie symbole rozmiarów plików na poniższej liście. Rozmiary plików będą składać się z liczby (z kropką dziesiętną lub bez), po której następuje KB, MBlub : GBTB
wzór:
ciąg znaków:   11TB 13 14,4MB 22HB 9,9GB TB 0KB 
mecze: ^^^^ ^^^^^^ ^^^^^ ^^^  
( Rozwiązanie )

Krok 9: „opcjonalny” znak zapytania?

RegEx: 20 krótkich kroków do opanowania wyrażeń regularnych.  Część 2 - 3Czy napisałeś już wyrażenie regularne, aby rozwiązać ostatni problem? Zadziałało? Teraz spróbuj zastosować go tutaj:
wzór:
ciąg znaków: 1..3KB 5...GB ..6TB
mecze:  
Oczywiście żadne z tych oznaczeń nie jest prawidłowym rozmiarem pliku, więc dobre wyrażenie regularne nie powinno pasować do żadnego z nich. Rozwiązanie, które napisałem, aby rozwiązać ostatni problem, pasuje do nich wszystkich, przynajmniej częściowo:
wzór: \d+\.*\d*[KMGT]B 
ciąg:   1..3KB  5...GB .. 6TB 
dopasowania: ^^^^^^ ^^^^^^ ^^^ 
( Przykład ) Więc w czym problem? W rzeczywistości musimy znaleźć tylko jedną kropkę dziesiętną, jeśli taka istnieje. Ale *pozwala na dowolną liczbę dopasowań, w tym zero. Czy istnieje sposób, aby dopasować tylko zero razy lub jeden raz? Ale nie więcej niż raz? Oczywiście, że mam. „opcjonalny” ?to modyfikator pasujący do zera lub jednego z poprzedzających znaków, ale nie więcej:
wzór: \d+\.?\d*[KMGT]B 
ciąg: 1.. 3KB 5...GB .. 6TB 
dopasowania:     ^^^ ^^^ 
( Przykład ) Jesteśmy bliżej rozwiązania, ale to nie do końca to, czego potrzebujemy. Zobaczymy, jak rozwiązać ten problem w kilku krokach nieco później.

W międzyczasie rozwiążmy ten problem:

W niektórych językach programowania (np. Java) po liczbach całkowitych i zmiennoprzecinkowych (kropkach) mogą występować l/ Li f/ F, aby wskazać, że należy je traktować jako długie/zmiennoprzecinkowe (odpowiednio), a nie jako zwykłe int/double. Znajdź wszystkie prawidłowe „długie” liczby w wierszu poniżej:
wzór:
ciąg:   13L długi 2l 19 L lL 0 
dopasowań: ^^^ ^^ ^^ ^ 
( Rozwiązanie )

Krok 10: znak „lub”.|

RegEx: 20 krótkich kroków do opanowania wyrażeń regularnych.  Część 2 - 4W kroku 8 mieliśmy pewne trudności ze znalezieniem różnych typów liczb zmiennoprzecinkowych:
wzór: \d*\.\d+ 
ciąg:   0,011 ,2 42 2,0 3,33 4,000 5 6 7,89012 
dopasowania: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
Powyższy wzór dopasowuje liczby z kropką dziesiętną i co najmniej jedną cyfrą po prawej stronie przecinka. Ale co, jeśli chcemy także dopasować ciągi takie jak 0.? (Brak liczb po prawej stronie przecinka dziesiętnego.) Wyrażenie regularne możemy napisać w ten sposób:
wzór: \d*\.\d* 
ciąg:   0,011 ,2 42 2,0 3,33 4,000 5 6 7,89012 0. . 
mecze: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ ^ 
( Przykład ) To pasuje 0., ale pasuje także do pojedynczego punktu ., jak widać powyżej. Właściwie to, co próbujemy dopasować, to dwie różne klasy ciągów:
  1. liczby mające co najmniej jedną cyfrę po prawej stronie przecinka dziesiętnego
  2. liczby mające co najmniej jedną cyfrę po lewej stronie przecinka
Zapiszmy następujące 2 wyrażenia regularne, niezależne od siebie:
wzór: \d*\.\d+ 
ciąg:   0,011 ,2 42 2,0 3,33 4,000 5 6 7,89012 0. .
mecze: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^  
wzór: \d+\.\d* 
ciąg:   0,011 ,2 42 2,0 3,33 4,000 5 6 7,89012 0. .
mecze: ^^^^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ 
Widzimy, że w żadnym z tych przypadków podciągi 42, lub nie 5są odnajdywane przez silnik. Aby uzyskać wymagany wynik, nie zaszkodzi nam połączyć te wyrażenia regularne. Jak możemy to osiągnąć? Znak „lub” pozwala nam określić w wyrażeniu regularnym kilka możliwych sekwencji dopasowań na raz. Tak jak znak „lub” pozwala nam określić alternatywne znaki pojedyncze, tak możemy określić alternatywne wyrażenia wieloznakowe. Na przykład, jeśli chcielibyśmy znaleźć „pies” lub „kot”, moglibyśmy napisać coś takiego: 6.|[]|
wzór: \w\w\w 
string:   Oczywiście , pies jest lepszym zwierzakiem niż kot .
mecze: ^^^^^^^^^ ^^^ ^^^^^^ ^^^ ^^^ ^^^ 
( Przykład ) ... ale to pasuje do wszystkich potrójnych sekwencji znaków klasy „word”. Ale „pies” i „kot” nie mają nawet wspólnych liter, więc nawiasy kwadratowe nam tutaj nie pomogą. Oto najprostsze wyrażenie regularne, jakiego możemy użyć, które pasuje do obu i tylko tych dwóch słów:
wzór: pies|kot 
string: Oczywiście, pies jest lepszym zwierzakiem niż kot .
mecze:               ^^^ ^^^ 
( Przykład ) Silnik wyrażeń regularnych próbuje najpierw dopasować całą sekwencję po lewej stronie znaku |, ale jeśli to się nie powiedzie, następnie próbuje dopasować sekwencję po prawej stronie znaku |. Wiele znaków |można również połączyć w łańcuch, aby dopasować więcej niż dwie alternatywne sekwencje:
wzór: pies|kot|zwierzę 
ciąg: Oczywiście, pies jest lepszym zwierzakiem niż kot .
mecze:               ^^^ ^^^ ^^^ 
( Przykład )

Rozwiążmy teraz kilka kolejnych problemów, aby lepiej zrozumieć ten krok:

Użyj znaku |, aby poprawić powyższe dziesiętne wyrażenie regularne i uzyskać taki wynik:
wzór:
ciąg:   0,011 ,2 42 2,0 3,33 4,000 5 6 7,89012 0. .
mecze: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ 
( Rozwiązanie ) Użyj znaku |, klasy znaków, "opcjonalne" ?itp., aby utworzyć pojedyncze wyrażenie regularne pasujące zarówno do liczb całkowitych, jak i zmiennoprzecinkowych (kropek), jak omówiono w problemie na końcu poprzedniego kroku (ten problem jest trochę bardziej skomplikowane, tak ;))
wzór:
ciąg:   42L 12 x 3,4f 6l 3,3 0F LF .2F 0. 
mecze: ^^^ ^^ ^^^^ ^^ ^^^ ^^ ^^^ ^^  
( Rozwiązanie ) 20 krótkich kroków do opanowania wyrażeń regularnych. Część 3 RegEx: 20 krótkich kroków do opanowania wyrażeń regularnych. Część 4
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION