Wyrażenia regularne to rodzaj wzorców, do których dopasowuje się
fragmenty różnych tekstów.
Nazwy tej używa się w dwóch kontekstach.
Pierwszy z nich dotyczy wyrażeń regularnych, jakie
można znaleźć np. przy wyszukiwaniu tekstu,
w bardziej rozbudowanych edytorach tekstów.
Są one również szeroko stosowane w Uniksie, w różnego rodzaju
programach do wyszukiwania i przetwarzania informacji tekstowych,
np. grep, awk i sed,
a także w generatorze analizatorów leksykalnych Lex.
Terminu tego używa się również w teorii języków
formalnych w podobnym znaczeniu.
Jednak w tym przypadku liczba konstrukcji jakie mogą być używane
do budowy wyrażeń regularnych jest ograniczona do absolutnego
minimum.
Jest to poniekąd naturalne, gdyż oba rodzaje wyrażeń regularnych
służą innym celom.
W pierwszym przypadku ma to być wygodny w użyciu język,
pozwalający na zwięzłe zapisywanie wzorców.
Stąd jest od dosyć rozbudowany i zawiera wiele konstrukcji.
W drugim przypadku bardziej nas interesuje badanie samych
wyrażeń regularnych i ich siły wyrazu.
Stąd język tych wyrażeń regularnych jest maksymalnie
uproszczony, a wszystkie konstrukcje, które można wyrazić w inny
sposób zostały z niego usunięte.
W trakcie tego kursu będziemy używali obu rodzajów
,,wyrażeń regularnych''.
Musimy więc nadać im różne nazwy.
Wyrażenia regularne takie, jak są używane w Lex'ie, będziemy
nazywać wzorcami.
Natomiast sam termin ,,wyrażenia regularne'' zarezerwujemy
dla takiego jego znaczenia, jakie ma w teorii języków
formalnych.
Na potrzeby tego rozdziału ustalamy jako domyślny alfabet
zbiór znaków ASCII.
Poniżej podajemy definicję wzorców.
Z jednej strony jest ona wzorowana na wyrażeniach regularnych
w Lex'ie, ale nie wymieniliśmy tutaj wszystkich dostępnych
tam konstrukcji.
Z drugiej strony dodaliśmy dwie konstrukcje, które nie są
dostępne w Lex'ie.
Definicja ta, oprócz składni wzorców, opisuje też nieformalnie
ich semantykę.
Semantyka ta jest bardziej formalnie zdefiniowana dalej.
Definicja
Wzorce, to wyrażenia, które możemy budować w
podany poniżej sposób.
- dla
, a jest wzorcem, do którego
pasuje tylko słowo a (chyba, że a ma jakieś specjalne
znaczenie opisane poniżej),
jest wzorcem, do którego pasuje tylko słowo
puste (ta konstrukcja nie jest dostępna w Lex'ie),
jest wzorcem, do którego nie pasuje żadne
słowo (ta konstrukcja nie jest dostępna w Lex'ie),
- . to wzorzec, do którego pasuje dowolny znak
(oprócz końca wiersza),
- ``x'' to wzorzec, do którego pasuje tylko słowo x
(nawet jak zawiera jakieś znaki o specjalnym znaczeniu),
-- ma analogiczne znaczenie jak w C,
np.
oznacza znak nowej linii,
-
to wzorzec, do którego pasuje dowolny ze znaków
wymienionych w kwadratowych nawiasach, np.
do [abc] pasuje dowolny ze znaków a, b i c,
-
[a-b] to wzorzec, do którego pasuje dowolny znak
od a do b,
zakresy takie można łączyć, np. [a-zA-Z] to
wzorzec, do którego pasuje dowolna litera, mała lub
wielka,
-
[^
to wzorzec, do którego pasuje dowolny znak
oprócz znaków wymienionych wewnątrz kwadratowych nawiasów,
np. do [^xyz] pasuje dowolny znak oprócz x, y i z,
- jeśli
jest wzorcem, to
jest wzorcem, do którego pasuje
oraz wszystkie te słowa, które pasują do
,
- jeśli
jest wzorcem, to
jest wzorcem, do którego pasuje sklejenie zera
lub więcej słów pasujących do
,
- jeśli
jest wzorcem, to
jest wzorcem, do którego pasuje sklejenie
jednego lub więcej słów pasujących do
,
- jeśli
i
są wzorcami, to
jest wzorcem, do którego pasują
sklejenia słów pasujących do
i słów pasujących do
,
- jeśli
i
są wzorcami, to
jest wzorcem, do którego pasują te
słowa, które pasują do
lub do
,
- jeśli
i
są wzorcami, to
jest wzorcem, do którego pasują te
słowa, które pasują równocześnie do
i
(ta konstrukcja nie jest dostępna w Lex'ie),
- jeśli
jest wzorcem, to
jest wzorcem, do którego pasują
wszystkie te słowa, które nie pasują do
(ta konstrukcja nie jest dostępna w Lex'ie),
- jeśli
jest wzorcem, to
jest nim również
i pasują do niego te same
słowa, co do
-- inaczej mówiąc, do budowy
wzorców możemy używać nawiasów,
Przykład
Oto garść przykładowych wzorców:
- [0-9]+ opisuje (niepuste) ciągi cyfr, czyli
zapisy dziesiętne liczb naturalnych.
- Do wzorca
pasuje tylko słowo abba.
Do a*bba* pasują słowa zawierające dokładnie dwie
litery b i to położone obok siebie, a
do
pasują słowa zbudowane z ,,cegiełek''
ab i ba.
Jedynym słowem, które pasuje do obydwu tych wzorców jest
właśnie abba.
- Wzorzec
[A-Z][A-Z] [0-9][0-9][0-9][0-9][0-9] opisuje
jedną z form numerów rejestracyjnych, złożonych z dwóch
liter i pięciu cyfr.
Zdefiniujemy teraz bardziej formalnie semantykę wzorców.
Definicja
Niech

i

będą wzorcami.
Przez

oznaczamy język opisywany przez wzorzec

, czyli język złożony z tych słów, które
pasują do wzorca

.

definiujemy indukcyjnie ze względu na budowę
wzorca

:
- L(a) = {a}, dla
, o ile a nie ma
specjalnego znaczenia opisanego niżej,
-
,
-
,
-
,
- L(``x'') = {x},
-
,
-
-- zależy od kolejności
znaków w kodowaniu ASCII,
-
-
,
-
,
-
,
-
,
-
,
-
,
-
,
-
.
Badając wzorce często będziemy chcieli porównywać nie tyle je
same, ale ich znaczenia.
Przyda nam się do tego pojęcie równoważności wzorców.
Definicja
Powiemy, że dwa wzorce

i

są równoważne,

, wtw., gdy

.
Oto garść tożsamości dotyczących wzorców.
Niektóre z nich, tak naprawdę, poznaliśmy już w poprzednim
wykładzie jako tożsamości dotyczące języków.
-
--
to nic innego jak rozdzielność sklejania języków względem
ich sumowania, zastosowana do wzorców,
-
-- j.w.,
-
--
jest ,,zerem'' sklejania, również dla wzorców,
-
--
oto dwie rekurencyjne definicje operacji +,
-
,
-- oba wzorce opisują naprzemienne ciągi
i
zaczynające i kończące się
-ą,
-
--
domykanie domknięcia Kleene'ego nie wnosi nic dodatkowego,
-
-- ciąg
i
można zawsze przedstawić jako
poprzeplatane ze sobą ciągi
i ciągi
(wliczając w to ciągi długości zero),
i vice versa.
Okazuje się, że wiele z konstrukcji występujących we
wzorcach może być zastąpionych prostszymi konstrukcjami.
Na przykład zamiast [a-c] można napisać
.
Postępując w ten sposób, każdy wzorzec można przerobić na taki,
który został zapisany przy użyciu tylko pewnego minimalnego zestawu
konstrukcji.
Wzorce, które możemy zapisać przy użyciu owego
minimalnego zestawu operacji, nazywamy
wyrażeniami regularnymi.
Definicja
Wyrażenia regularne, to takie wzorce, które są zbudowane
tylko przy użyciu:
,
,
- a, dla
,
,
gdzie
i
to wyrażenia regularne,
-
,
gdzie
i
to wyrażenia regularne,
,
gdzie
to wyrażenie regularne,
,
gdzie
to wyrażenie regularne.
Jak zobaczymy dalej, wszystkie pozostałe konstrukcje są
redundantne, choć w praktyce są przydatne.
Wyrażenia regularne będą nam potrzebne wówczas, gdy będziemy się
zajmowali tym, co można wyrazić za pomocą wzorców i ogólnymi
właściwościami języków, które można opisywać za pomocą wzorców.
Dzięki ograniczeniu zestawu możliwych konstrukcji do niezbędnego
minimum, nasze rozważania będą prostsze.
Klasę języków, dla których istnieją opisujące je wzorce nazywamy
językami regularnymi.
Definicja
Powiemy, że język
A jest
regularny, wtw., gdy
istnieje wzorzec

opisujący
A, czyli

.
Jak później pokażemy, wzorce mają taką samą siłę wyrazu co
wyrażenia regularne, tzn. jeśli dla danego języka istnieje
opisujący go wzorzec, to istnieje również opisujące go wyrażenie
regularne.
Jeden z problemów, jakim będziemy się zajmować w trakcie tego
kursu, to: jakie języki są regularne?
Okazuje się, że nie wszystkie.
Poniżej podajemy kilka prostych własności klasy języków
regularnych.
Niech
będzie niepustym skończonym językiem.
Język ten można opisać wzorcem (a dokładniej wyrażeniem
regularnym) postaci
.
Język pusty można opisać wzorcem
.
Skoro A i B są regularne, to istnieją opisujące je wzorce
i
,
,
.
Interesujące nas języki są regularne, bo opisują je wzorce:
,
,
,
i
.
W tym wykładzie poznaliśmy wzorce oraz wyrażenia regularne.
Języki jakie można za ich pomocą opisać tworzą klasę języków
regularnych.
- Język opisywany
przez wzorzec to język złożony
z tych słów, które pasują do wzorca
.
- Język regularny,
to taki język, dla którego istnieje opisujący go
wzorzec.
- Wyrażenia regularne
to szczególny przypadek wzorców,
do których zapisu użyto wyłącznie:
symboli alfabetu,
,
,
sklejania,
, * i nawiasów.
- Wzorce
to rodzaj wyrażeń, do których dopasowujemy słowa nad ustalonym
alfabetem.
Wzorzec opisuje język złożony ze słów, które do niego
pasują.
- Podaj wyrażenie regularne równoważne wzorcowi:
.
- Podaj wzorzec opisujący poprawne numery indeksów
studentów, np. postaci s0124.
- Uprość następujący wzorzec
.
- Podaj wzorce/wyrażenia regularne opisujące język złożony ze
słów:
- nad alfabetem {a,b}, które zawierają podsłowo bbab,
- nad alfabetem {a,b,c}, które zaczynają się i kończą
tym samym znakiem,
- nad alfabetem {a,b}, które nie zawierają podsłowa aa,
- nad alfabetem {a,b}, które nie zawierają podsłowa ab,
- nad alfabetem {a,b,c}, które nie zawierają podsłowa aa,
- nad alfabetem {a,b,c}, które nie zawierają podsłowa ab,
- nad alfabetem {a,b,c} złożonych tylko z jednego
rodzaju symboli,
- nad alfabetem {a,b,c} złożonych co najwyżej z dwóch
rodzai symboli,
- nad alfabetem {a,b}, które zawierają parzystą liczbę
liter a.
- Porównaj podane wzorce pod kątem równoważności / zawierania się
odpowiadających im języków.
Jeśli są równoważne, to uzasadnij to.
Jeżeli nie, to podaj przykład słowa, które pasuje do jednego
wzorca, ale nie do drugiego.
- (a? b?)* i
,
i
,
- (a*b)* i (b*a)*,
i
,
-
i
.