JavaRush /Blog Java /Random-PL /Podstawy wyrażeń regularnych w Javie. Część 3
articles
Poziom 15

Podstawy wyrażeń regularnych w Javie. Część 3

Opublikowano w grupie Random-PL
Kontynuujmy naukę wyrażeń regularnych. W tym artykule przyjrzymy się predefiniowanym klasom znaków oraz kwantyfikacji (wyszukiwaniu sekwencji). Podstawy wyrażeń regularnych w Javie.  Część 3 - 1

Predefiniowane klasy znaków

Interfejs API klas Patternzawiera predefiniowane klasy znaków, które oferują wygodne skróty do często używanych wyrażeń regularnych. Podstawy wyrażeń regularnych w Javie.  Część 3 - 2W tej tabeli konstrukcje w lewej kolumnie są skróconymi reprezentacjami wyrażeń w prawej kolumnie. Na przykład \doznacza cyfrę (0-9), \woznacza dowolną wielką lub małą literę, podkreślenie lub cyfrę). Jeśli to możliwe, używaj predefiniowanych klas znaków. Dzięki temu Twój kod będzie łatwiejszy do odczytania i naprawienia błędów. Konstrukcje zaczynające się od ukośnika odwrotnego nazywane są znakami ucieczki lub chronionymi. W poprzednich artykułach mówiliśmy już o uciekaniu od znaków specjalnych za pomocą ukośników odwrotnych lub symboli \Qi \Eużywaniu ich jako zwykłych znaków. Jeśli używasz ukośnika odwrotnego ze zwykłymi znakami (literałami), musisz uciec przed ukośnikiem odwrotnym, aby wyrażenie się skompilowało.
private final String REGEX = "\\d"; // цифра
W tym przykładzie \dwyrażenie regularne; dodatkowy ukośnik odwrotny jest niezbędny do skompilowania programu. Nasz program testowy odczytuje wyrażenia regularne bezpośrednio z konsoli, więc nie jest potrzebny żaden dodatkowy ukośnik. Poniższy przykład ilustruje użycie predefiniowanych klas znaków: Podstawy wyrażeń regularnych w Javie.  Część 3 - 3Podstawy wyrażeń regularnych w Javie.  Część 3 - 4W pierwszych trzech przykładach wyrażeniem regularnym jest po prostu „ .” (znak specjalny kropki), co oznacza dowolny znak. Dlatego poszukiwania zakończyły się sukcesem we wszystkich przypadkach. Inne przykłady wykorzystują predefiniowane klasy znaków, których znaczenie omówiliśmy w powyższej tabeli.

Kwantyfikatory

Podstawy wyrażeń regularnych w Javie.  Część 3 - 4Kwantyfikatory pozwalają określić liczbę wystąpień znaku w ciągu. Przyjrzyjmy się bliżej zawiłościom działania kwantyfikatorów zachłannych, leniwych i bardzo zachłannych. Na pierwszy rzut oka może się wydawać, że kwantyfikatory X?, X?? i X?+ działają w ten sam sposób: „X jest obecny raz lub wcale”. Istnieją niewielkie różnice w implementacji tych kwantyfikatorów, którym przyjrzymy się poniżej.

Dopasowania o zerowej długości

Zacznijmy od chciwego. Zapiszmy trzy różne wyrażenia regularne: literę „a” ze znakami specjalnymi ?, * lub +. Zobaczmy, co się stanie, jeśli przetestujemy te wyrażenia regularne w pustej linii: Podstawy wyrażeń regularnych w Javie.  Część 3 - 5W powyższym przykładzie wyszukiwanie zakończyło się sukcesem w pierwszych dwóch przypadkach, ponieważ wyrażenia a? i a* pozwalają na brak znaku a w ciągu. Należy również pamiętać, że indeks rozpoczęcia i ostatniego dopasowania są takie same (0). Ponieważ ciąg wejściowy nie ma długości, program nie znajduje niczego :) na pierwszej pozycji. Ten przypadek nazywa się dopasowaniem o zerowej długości. Takie dopasowania mają miejsce w kilku przypadkach: gdy linia wejściowa jest pusta, na początku linii wejściowej, po ostatnim znaku linii lub pomiędzy znakami w linii. Dopasowania o zerowej długości są łatwe do wykrycia: zaczynają się i kończą w tej samej pozycji. Przyjrzyjmy się jeszcze kilku przykładom dopasowań o zerowej długości. Przyjrzyjmy się dopasowaniom o zerowej długości na kilku kolejnych przykładach. Zmieńmy ciąg wejściowy na znak „a” i zaobserwujmy ciekawy efekt: Podstawy wyrażeń regularnych w Javie.  Część 3 - 6wszystkie trzy kwantyfikatory znalazły znak „a”, ale pierwsze dwa, które uwzględniają brak znaku, znalazły dopasowanie o zerowej długości na pozycji 1 - po ostatnim znaku ciągu. Dzieje się tak, ponieważ program traktuje znak „a” jako ciąg znaków i „przegląda” go, aż nie będzie już żadnych dopasowań. W zależności od użytego kwantyfikatora program znajdzie lub nie znajdzie „nic” na końcu łańcucha. Zmieńmy teraz ciąg wejściowy na ciąg pięciu liter „a”: Podstawy wyrażeń regularnych w Javie.  Część 3 - 7Wyrażenie regularne a? znajduje dopasowanie dla każdej litery w ciągu oddzielnie. Wyrażenie a* znajduje dwa dopasowania: sekwencję znaków „a” i dopasowanie o zerowej długości na pozycji 5. I wreszcie wyrażenie regularne a+ wyszukuje tylko ciąg znaków „a”, nie znajdując „nic” :) Co się stanie, jeśli na wejściu zostanie podany ciąg znaków zawierający różne znaki? Na przykład „ababaaaab”: Podstawy wyrażeń regularnych w Javie.  Część 3 - 8Znak „b” znajduje się na pozycjach 1, 3 i 8, a program znajduje na tych pozycjach dopasowania o zerowej długości. Wyrażenie regularne a? nie zwraca uwagi na „b”, ale po prostu szuka obecności (lub nieobecności) znaku „a”. Jeśli kwantyfikator dopuszcza brak „a”, wszystkie znaki w ciągu inne niż „a” zostaną pokazane jako dopasowanie o zerowej długości. Aby znaleźć ciągi o określonej długości, po prostu określ długość w nawiasach klamrowych: Podstawy wyrażeń regularnych w Javie.  Część 3 - 9Wyrażenie regularne a{3} wyszukuje ciąg trzech znaków „a”. Nic nie zostało znalezione w pierwszym wierszu, ponieważ nie było wystarczającej liczby „a” w wierszu. Drugi zawiera 3 znaki, które program znajdzie. Trzeci test również znajduje dopasowanie na początku ciągu. Wszystko po trzecim znaku nie spełnia wyrażenia regularnego, w poniższym kodzie tak jest i będzie kilka dopasowań: Podstawy wyrażeń regularnych w Javie.  Część 3 - 10Aby określić minimalną długość sekwencji, użyj:
Enter your regex: a{3,}
Enter input string to search: aaaaaaaaa
I found the text "aaaaaaaaa" starting at index 0 and ending at index 9.
W tym przykładzie program znajduje tylko jedno dopasowanie, ponieważ ciąg spełnia wymagania dotyczące minimalnej długości sekwencji wynoszącej (3) znaki „a”. Na koniec ustawienie maksymalnej długości sekwencji: Podstawy wyrażeń regularnych w Javie.  Część 3 - 11W tym przykładzie pierwsze dopasowanie zakończyło się na szóstym znaku. Drugie dopasowanie zawiera znaki występujące po szóstym, ponieważ spełniają wymagania dotyczące minimalnej długości. Jeśli ciąg znaków byłby o jeden znak krótszy, drugie dopasowanie nie byłoby możliwe.

Używanie grup i klas znaków z kwantyfikatorami

Do tego momentu testowaliśmy kwantyfikatory na ciągach zawierających ten sam znak. Kwantyfikatory dotyczą tylko pojedynczego znaku, więc wyrażenie regularne „abc+” dopasuje ciągi zawierające „ab” i „c” jeden lub więcej razy. Nie będzie to oznaczać „abc” jeden lub więcej razy. Ale kwantyfikatorów można używać w połączeniu z grupami i klasami znaków, takimi jak [abc]+ (a lub b lub c, jeden lub więcej razy) lub (abc)+ („abc” jeden lub więcej razy). Znajdźmy grupę znaków (pies) trzy razy w linii: Podstawy wyrażeń regularnych w Javie.  Część 3 - 12W pierwszym przykładzie program znajduje dopasowanie, ponieważ kwantyfikator rozciąga się na grupę znaków. Jeśli usuniesz nawiasy, kwantyfikator {3} będzie miał zastosowanie tylko do litery „g”. Kwantyfikatorów można używać także z klasami znaków: Основы регулярных выражений в Java. Часть 3 - 13Kwantyfikator {3} dotyczy w pierwszym przykładzie klasy znaków podanej w nawiasie, a w drugim – tylko znaku „c”.

Różnice między kwantyfikatorami zachłannymi, leniwymi i nadmiernie zachłannymi

Istnieją niewielkie różnice między kwantyfikatorami zachłannymi, niechętnymi i zaborczymi. Kwantyfikatory zachłanne zostały tak nazwane, ponieważ próbują znaleźć najdłuższe możliwe dopasowanie: program najpierw próbuje „zjeść” cały ciąg, jeśli dopasowanie nie zostanie znalezione, wówczas jeden znak jest odrzucany i wyszukiwanie jest powtarzane aż do znalezienia dopasowania lub nie ma już więcej znaków. Z drugiej strony leniwi ludzie zaczynają od początku wiersza, dodając znak po znaku, aż znajdą dopasowanie. Wreszcie zazdrosna kwantyfikacja skanuje raz cały ciąg, bez usuwania znaków, jak w przypadku zachłanności. Do demonstracji użyjemy ciągu xfooxxxxxxfoo. Основы регулярных выражений в Java. Часть 3 - 14W pierwszym przykładzie zastosowano zachłanny kwantyfikator .* do znalezienia dowolnego znaku 0 lub więcej razy, po którym następują znaki „f”, „o” „o”. Ponieważ kantyfikator jest zachłanny, znalezione dopasowanie zawiera cały ciąg. Zachłanny kwantyfikator nie znajdzie wszystkich dopasowań w ciągu, ponieważ w pierwszym kroku, po zeskanowaniu całego ciągu, znajdzie dopasowanie i zakończy zadanie. Drugi przykład jest leniwy i zaczyna się od początku linii, dodając znak po znaku. Program rozpoczyna się od sprawdzenia „pustki”, ale od sekwencja „foo” nie znajduje się na początku linii, wyszukiwanie jest kontynuowane przez dodanie znaku „x”, po czym zostanie znalezione pierwsze dopasowanie pomiędzy indeksami 0 i 4. Wyszukiwanie trwa do końca linii a drugie dopasowanie zostanie znalezione pomiędzy indeksami 4 i 13. Trzeci przykład nie znajduje zbieżności, ponieważ kwantyfikator jest zazdrosny. W tym przypadku wyrażenie regularne .*+ „zjadło” całą linię, nie pozostawiając nic dla „foo”. Użyj kwantyfikatora zazdrosnego, jeśli chcesz odrzucić wszystko, co niepotrzebne w ciągu znaków. Będzie on skuteczniejszy niż równoważny kwantyfikator zachłanny. To wszystko! Link do źródła: Podstawy wyrażeń regularnych w Javie. Część 3
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION