Wyrażenia regularne i wykorzystanie ich w języku Java

Download Report

Transcript Wyrażenia regularne i wykorzystanie ich w języku Java

Wyrażenia regularne i
wykorzystanie ich w języku Java
Wprowadzenie
Wyrażenia regularne (ang. regular expressions, w skrócie regex lub
regexp) – wzorce, które opisują łańcuchy symboli. Teoria wyrażeń
regularnych jest związana z teorią języków regularnych. Wyrażenia
regularne mogą określać zbiór pasujących łańcuchów, mogą również
wyszczególniać istotne części łańcucha.
zastosowanie - bardziej złożone dopasowywanie ciągów (np. sprawdzanie
poprawności dat, zastępowanie jednych fragmentów tekstu innymi,
pobieranie fragmentów z większych bloków tekstu)
2 style składni wyrażeń regularnych: unixowa i perlowa
w połączeniu z konkretnym narzędziem,w którym zostały
zaimplementowane, umożliwiają różnorodne sposoby przetwarzania tekstu.
Wprowadzenie
•
•
•
•
•
•
•
Przetwarzanie tekstu:
walidacja formularzy
poprawianie pomyłek
masowa zmiana wyrazów w tekście
usuwanie białych znaków
wyciąganie pewnych wyrazów pasujących do wzorca z tekstu
konwertowanie adresów www, generowanych dynamicznie na statyczne
i wiele innych operacji związanych z tekstem…
Przykład sprawdzania poprawności adresu poczy elektronicznej
(njpopularniejsza uproszczona forma)
^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\.([a-zAZ]{2,}){1}$.
Składnia
Znaki zwyczajne
a, b, c, z, A, B, C, Z, 0, 1, 2, 9, ,, !, _, @, #
Każdy znak, oprócz znaków specjalnych, określa sam siebie.
Ważna kolejość
Znaki specjalne (metaznaki)
– metaznaki rozpoznawane w dowolnym miejscu wzorca poza
nawiasami kwadratowymi [ ] – ^, $, ., *, ?, +, [, ], {, }, (, ), \
– metaznaki rozpoznawane w klasach znaków (część wzorca ujęta
w nawiasy kwadratowe [ ], pasująca do dokładnie jednego znaku,
bez względu na liczbę tworzących ją znaków) – ^, -, \, ]
Znaki specjalne
Kropka . – oznacza dowolny znak, z wyjątkiem znaku nowego
wiersza, np: .o.a pasuje do lola, cola, wola, kolacja itp.
Znaki specjalne poprzedzone odwrotnym ukośnikiem \ oznaczją
siebie
Pionowa kreska | to operator OR np. jeśli napiszemy a|b|c oznacza
to, że w danym wyrażeniu może wystąpić a lub b lub c.
Grupowanie ( ). Podwzorzec może być zamknięty w niepodzielnej
grupie za pomocą nawiasów. W ten sposób można użyć gałęzi nie
tylko dla całego wzorca, ale również dla jego fragmentów np:
Fizy(cy|k) – pasuje do Fizycy i Fizyk
Zestaw znaków między nawiasami kwadratowymi oznacza dowolny
znak objęty nawiasami kwadratowymi, np:
[1234], [1-4] – oznacza 1 lub 2 lub 3 lub 4
pi[wk]o – pasuje do piwo i piko
Klasy znaków (java – klasa pattern)
[abc] – a, b albo c (klasa prosta)
[^abc] – jakikolwiek znak za wyjątkiem a, b, c (negacja)
[a-zA-Z] – a do z oraz A do Z
Polskie znaki – najpewniej podać pełen zakres tzn.
[0-9a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ]
[a-d[m-p]] – a do d albo m do p (unia)
[a-z&&[def]] – d, e albo f (przecięcie)
[a-z&&[^bc]] – a do z za wyjątkiem b i c (różnica)
[a-z&&[^m-p]] – a do z i nie m do p (różnica)
Klasy znaków
Ze względu na to, że zarówno [-] jak i [^] mają specjalne znaczenie,
jeśli umieszczamy je w nawiasach kwadratowych:
– chcąc dopasować daszek [^] nie należy umieszczać go na początku;
– chcąc dopasować minus [-] najbezpieczniej umieścić go jako ostatni
znak w zakresie;
Zamiast [^%$#@!], należy zastosować [%$#@!^], a zamiast
[a-c], chcąc dopasować ‘a’, ‘c’ lub ‘–’ należy zastosować [ac-].
Reprezentacje znaków
(predefined character classes)
. – jakikolwiek znak
\d – cyfra: [0-9]
\D – nie cyfra: [^0-9]
\s – „biały” znak: [ \t\n\x0B\f\r]
\S – nie „biały” znak: [^\s]
\w – znak „literowy” (word character): [a-zA-Z_0-9]
\W – znak nie „literowy”: [^\w]
private final String REGEX = "\\d"; // pojedyncza cyfra
Ograniczenia - kotwiczenie
(boundary matches)
^ – początek linii
$ – koniec linii
regex: ^dog$ -> string to search: dog -> tak
regex: ^dog$ -> string to search:
dog -> nie
\b – słowo ograniczające
regex: \bdog\b -> string to search: The dog plays in the yard. -> tak
regex: \bdog\b -> string to search: The doggie plays in the yard. -> nie
\B – odwrotnie niż w przykładzie powyżej
regex: \bdog\B -> string to search: The dog plays in the yard. -> nie
\G – koniec wcześniejszego dopasowania
regex: \Gdog -> string to search: dog dog -> tylko jedno dopasowanie (po
pierwszym dopasowaniu spacja)
Powtórzenia - kwantyfikatory
powtarzalność można określić stosując znaki specjalne:
(dotyczy greedy)
* - wzór może powtórzyć się zero bądź więcej razy
+ - wzór może powtórzyć się jeden bądź więcej razy
? - wzór może wystąpić jeden bądź wcale
np. ko?t pasuje do kt, kot
ko*t pasuje do kt, kot, koot, koooooot, ...
ko+t pasuje do kot, koot, koooooot, ...
wyrażenie można rozdzielić na podwyrażenia stosując nawiasy
jak w zwykłych wyrażeniach arytmetycznych np.
(bardzo)* dużo pasuje do 'dużo', 'bardzo dużo', 'bardzo bardzo
dużo'
Powtórzenia - kwantyfikatory
• relucant – dodajemy po właściwym kwantyfikatorze ?
• possesive – dodajemy po właściwym kwantyfikatorze +
Enter your regex: .*foo // greedy
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.
Enter your regex: .*?foo // reluctant
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.
Enter your regex: .*+foo // possessive
Enter input string to search: xfooxxxxxxfoo
No match found.
Kwantyfikatory
podwyrażenia policzalne - ilość powtórzeń danego ciągu
można określić stosując nawiasy klamrowe
• Wyrażenie {X} oznacza dokładnie X wystąpień
• Wyrażenie {X,} co najmniej X wystąpień, czyli przykładowo
{0,} = *, {1,} = +
• Wyrażenie {,X} co najwyżej X wystąpień
• Wyrażenie {X,Y} oznacza Y dopasowań (jeśli to możiwe), ale
nie mniej niż X, np: {0,1} = ?
np.:
{3} - dokładnie 3 powtórzenia
{2,4} - od dwu do czterech powtórzeń
{2,} - co najmniej dwa powtórzenia
Powtarzalność
przykład
Kwantyfikatory
regex: (dog){3}
string to search: dogdogdogdogdogdog -> podwójne dopasowanie
regex: dog{3}
string to search: dogdogdogdogdogdog -> nic
regex: [abc]{3}
string to search: abccabaaaccbbbc -> 5 dopasowań
regex: abc{3}
string to search: abccabaaaccbbbc -> nic
Wyrażenia
regularne
w javie
Powtarzalność
przykład
Klasa Pattern
Do obsługi wyrażeń regularnych w javie służą klasy Matcher i Pattern
z pakietu java.util.regex
Klasa Pattern nie ma konstruktorów a obiekt klasy zwracany
jest przez statyczną metodę compile(), której argumentem jest
ciąg znaków z wyrażeniem regularnym; compile powoduje
transformację wyrażenia regularnego do wzorca, np.:
Pattern wzorzec = Pattern.compile("wyrażenie_regularne");
Metoda matcher() klasy Pattern zwraca obiekt klasy Matcher;
argumentem metody jest ciąg znaków w którym będzie
poszukiwany wzorzec, np.:
Matcher sekwencja=wzorzec.matcher("ciąg_do_przeszukania");
Klasa PatternSyntaxException – wyjątek wskazujący błąd
składni we wzorcu
Wyrażenia
regularne
w javie
Powtarzalność
przykład
Klasa Pattern
import java.util.regex.*;
public class WyrazeniaRegularne {
public static void main(String[] args) {
//utworzenie wzorca regex:
Pattern wzorzec=Pattern.compile("[ks].+?e");
//utworzenie sekwencji zawierajacej wszystkie podciągi
//pasujące do wzorca wyszukane w podanym ciągu:
Matcher sekwencja=
wzorzec.matcher("konie, żyrafy, słonie, psy i koty");
//pobranie poszczególnych podciągów z sekwencji:
while (sekwencja.find())
{ System.out.println(sekwencja.group());
//wynik: konie słonie
}
}
Wyrażenia
regularne
w javie
Powtarzalność
przykład
Klasa Matcher
•
•
•
•
•
•
Nie posiada konstruktorów a do tworzenia obiektu używa się metody
matcher() klasy Pattern
Wybrane metody:
boolean find() – zwraca true, jeśli znaleziono sekwencję pasującą
do wzorca
String group() – zwraca ostatnio znalezioną pasującą sekwencję
int end() – zwraca indeks ostatniego znaku pasującej sekwencji
powiększony o 1
boolean matches() – zwraca true jeśli sekwencja(lub jej fragment)
pasuje do wzorca; wywołana po raz kolejny szuka kolejnego
pasującego fragmentu
String replaceAll(String nowy) - przeszukuje ciąg znaków i
zastępuje w nim pasujące sekwencje nowym ciągiem znaków
int start() - zwraca indeks pierwszego znaku pasującej sekwencji