Lingwistyka matematyczna

interaktywna pomoc do laboratorium

  • start
  • teoria
  • laboratorium
  • ćwiczenia
  • linki
Analizator składniowy
Podstawy budowania wyrażeń regularnych
Przejście z definicji gramatyki na wyrażenia regularne

Teoria

  • Analizator składniowy
  • Diagramy składni
  • Analizator ster. składn.
  • ONP
  • Automaty


Katedra
Informatyki Stosowanej
  • 90-924 Łódź
  • ul. Stefanowskiego 18/22
  • katedra@kis.p.lodz.pl

Podstawy budowy
wyrażeń regularnych

Wyrażeniami regularnymi nazywamy pewne wzorce, którymi możemy opisać łańcuchy symboli. Znalazły one bardzo szerokie zastosowanie i są wykorzystywane, nie tylko przy analizie składniowej podczas budowy kompilatorów, ale wszędzie tam, gdzie istnieje potrzeba szybkiego wyszukania w dokumencie określonego łańcucha znaków i porównania go ze wzorcem. Można oczywiście przeprowadzać tego typu procesy bez udziału wyrażeń regularnych, stosując tradycyjne funkcje i procedury, ale wydłuża to znacznie kod programu oraz czas obliczeń, choć pozornie programy mogą się wydawać prostsze do napisania. Przykładem zastosowania wyrażeń regularnych jest analiza kodu HTML strony internetowej, w celu wyodrębnienia z niego czystego tekstu, który jest widoczny w przeglądarce.


Definicja

Niech ∑ będzie alfabetem. Wyrażenia regularne nad ∑ i zbiory przez nie reprezentowane definiujemy rekursywne w następujący sposób:

  1. Ø jest wyrażeniem regularnym reprezentującym zbiór pusty

  2. ε jest wyrażeniem regularnym reprezentującym zbiór {ε}

  3. Dla każdego a z ∑, a jest wyrażeniem regularnym reprezentującym zbiór {a}

  4. Jeżeli r i s są wyrażeniami regularnymi reprezentującymi, odpowiednio, języki R i S, to (r + s), (rs) i (r*) są wyrażeniami regularnymi reprezentującymi, odpowiednio, zbiory R∪S, RS i R*

Z reguły 4 wynika, że:

  • e₁+e₂ oznacza aletrnatywę, albo e₁ albo e₂
  • e₁e₂ oznacza sekwencję, najpierw e₁ następnie e₂
  • e₁* oznacza dowolny ciąg składający się z e₁, także pusty
    (domknięcie Kleene'go) np. e₁e₁, e₁e₁e₁e₁e₁e₁


Przykładowo, wyrażenie regularne mo(ż + rz)e definiuje język, zawierający dwa słowa: "może" i "morze". To samo możemy zapisać w postaci: może+morze
W praktyce wyrażenia regularne zapisywane są za pomocą bogatszej składni, niż ta stosowana w informatyce teoretycznej. Obecnie są one częścią niektórych narzędzi systemowych oraz języków programowania, przetwarzających tekst, takich jak np. Pearl, a także stanowią osobne biblioteki znacznej większości języków programowania. Aktualnie dwiema najczęściej stosowanymi składniami są uniksowa i pearlowa. Ta ostatnia używana jest nie tylko w Perlu, ale także np. w C.



Podstawową składnię wyrażeń regularnych przedstawiono poniżej.

Klasy znaków:

.dowolny znak
[abc]dowolny znak ze wskazanego zbioru
[^abc]dowolny znak oprócz tych ze zbioru
[a-z0-9]dowolny znak z zakresu od a do z lub od 0 do 9
\wdowolny znak z klasy word (litera, cyfra, podkreślnik)
\Wdowolny znak spoza klasy word
\sdowolny biały znak (np. spacja)
\Sdowolny znak inny niż biały
\ddowolna cyfra
\Ddowolny znak inny niż cyfra


W poniższej znajdują się symbole, przy pomocy których można określić miejsce w tekście, w którym ma się pojawić dopasowanie do wzorca:

^dopasowanie musi się pojawić na początku tekstu
$dopasowanie musi się pojawić na końcu tekstu
\bdopasowanie musi się znajdować na początku lub końcu słowa
\Bdopasowanie nie może się znajdować na początku lub końcu słowa


Bardzo często istnieje potrzeba określenia ilości powtórzeń danego znaku lub ciągu znaków. Można to określić za pomocą symboli przedstawionych poniżej:

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


Istnieje jeszcze wiele elementów składni wyrażeń regularnych. Wybrane z nich (często przydatne) przedstawiono poniżej:

\Ukośnik pełni również funkcję znaku ucieczki Przykładowo wyrażenie \. oznacza po prostu kropkę
\0x20kod szesnastkowy znaku ASCII
\u0020kod szesnastkowy znaku Unicode
( )nawiasy zwykłe używane są do grupowania symboli
|pionowa kreska oznacza alternatywę


Jak wynika z powyższych tabel, składnia praktyczna wyrażeń regularnych różni się od składni teoretycznej. Ze względu na uproszczenie i niekiedy znaczne skrócenie zapisu, wprowadzenie składni praktycznej było naturalną koniecznością. Przykładowe różnice pokazują przykłady umieszczone poniżej:

Składnia teoretyczna

Składnia praktyczna

0+1+2+3+4+5+d+e+f+g+h+i+j+k[012345defghijk] lub [0-5d-k]
+|
kkkkkkkk{7}
kk*k+
k+εk?


Przykłady

Jak widać z powyższej tabeli składnia praktyczna znacznie upraszcza zapis wyrażeń regularnych, a ponadto daje więcej możliwości, ponieważ występują w niej elementy, których nie ma w składni teoretycznej.
Aby pokazać, jakie możliwości daje stosowanie wyrażeń regularnych, najlepiej odwołać się do konkretnych przykładów.
Załóżmy, że chcemy napisać wyrażenie regularne, sprawdzające poprawność zapisu kodu pocztowego. Ma on postać dwóch cyfr, po których następuje myślnik, a następnie jeszcze trzy cyfry (np. 05-840). Możemy zapisać kilka wyrażeń regularnych, które znajdą zastosowanie w tym przypadku. Poniżej przedstawiono cztery warianty, których wynik działania jest identyczny:

  • ^[0-9][0-9]-[0-9][0-9][0-9]$

  • ^[0-9]{2}-[0-9]{3}$

  • ^\d\d-\d\d\d$

  • ^\d{2}-\d{3}$

Kolejnym przykładem może być sprawdzanie poprawności zapisu liczby rzeczywistej, który składa się ze znaku + lub - (znak ten może wystąpić, ale nie musi), następnie występuje dowolna liczba cyfr, po której opcjonalnie może wystąpić kropka i rozwinięcie dziesiętne (np 3.1415, -25.87 itd.)

  • ^[+-]?[0-9]+(\.[0-9]+)?$

  • ^[+-]?\d{1,}(\.\d{1,})?$

  • ^[+-]?\d+(\.\d+)?$


Jak widzimy na podstawie prostych przykładów, istnieje wiele sposobów na opisanie lub sprawdzenie tego samego ciągu znaków za pomocą wyrażeń regularnych.

 

Katedra Informatyki Stosowanej | Wydzia EEiA | Politechnika Łódzka

copyright © Katedra Informatyki Stosowanej, designed by alpha studio
dostosowanie kodu i grafiki: Piotr Cieński