Do końca tej strony będę używać takiej konwencji:
wyrażenie regularne
i ciąg znaków, do którego wrażenie pasuje.
A zanim zaczniesz wypróbowywać wyrażenia w Vim-ie czy w grep-ie, przeczytaj komentarz z dołu stronki
Wyrażenie regularne to inaczej taki ciąg znaczków, że pewne inne ciągi
(niekoniecznie takie same) pasują do niego. Konkretnie do ciągu
[a-cw]*b+((ch)|(rz))?a.{2,4} może podpasować słowo
wrzask, podobnie z resztą, jak
ccabbbcbbaopp Fajne, co?
Zaczniemy od najprostszych wyrażeń (czy byłby sens zaczynać od
najtrudniejszych? :) ). Samo słowo, bez żadnych przecinków, nawiasów,
gwiazdek, plusów, pytajników i innych znaków przestankowych, tylko litery,
cyfry i spacja - oto najprostsze, co może być. Takie coś pasuje samo siebie
(czyli czasownik pasuje do słowa
czasownik i tylko do niego). Rozszerzmy
teraz naszą wiedzę conieco: gwiazdka *, pytajnik
? i plus + mają
specjalne znaczenie. Jeśli gwiazdka będzie występować za literką (powiedzmy)
s, to takie coś pasuje do braku s, do jednego s, do dwóch, trzech... do tylu,
ile się tylko da: w wyrażeniu ja sobie hopsasasa do
lassa do maski s*a dopasowane zostaną
a z wyrazu
ja, wszystkie
sa w trzecim wyrazie, pojedyncze
a i ssa
w drugim. Pytajnik z kolei pasuje do literki lub jej braku: maska
k?toś spasuje w wyrażeniu
ktoś sobie toś ttoś podpasuje wyrazy
ktoś i toś
i trzy ostatnie litery z ostatniego wyrazu. Drugie t nie zostanie włączone do
tego, co pasuje. Plus z kolei działa tak: w+erty
w wyrażeniu wwwwwwerty erty werty dopasuje
wyrazy pierwszy i trzeci, drugiego nie ruszając. Toto działa jak
ww*erty. Pasuje co najmniej jedną literkę, próbując
trafić jak najwięcej. Jeśli chcesz trafić samą gwiazdkę, plus czy pytajnik, to
poprzedź go/ją backslashem.
Weźmy teraz na warsztat nawiasy klamrowe {}. Te
mają dość fajne zastosowanie: x{2,5} pasuje
literkę x występującą od 2 do 5 razy, przy czym im więcej razy występuje, tym
lepiej. To jest równoważne wyrażeniu xxx?x?x?.
Można trafiać jak najmniej literek: x{-2,5} pasuje
tak, jak wyżej, z tym że raczej stara się trafić mniej literek (niestety, nie
ma przykładu na to dla pojedynczych liter, musiałbyś znać nieco więcej). Jak
chcesz trafić dokładnie pięć literek z, to możesz wstawić
zzzzz (co jest najprostszym wyjściem dla samych
liter, ale nie zdaje egzaminu przy bardziej złożonych wyrażeniach), albo
możesz wybrać z{5}. Możesz jeszcze pominąć
początkową liczbę przy zakresie ilości trafień, wtedy trafiasz od 0 do tylu,
ile wpisałeś, albo możesz pominąć końcową liczbę - trafiasz co najmniej tyle,
ile wpisałeś. W szczególności q{1,} jest
równoważne z q+,
a q{,1} = q? Fajne
jest też w{-1,} trafiające literki w, ale
zaznaczające jak najmniej (to również jest przydatne w bardziej
skomplikowanych wyrażeniach). Identyczna sytuacja, jak przy *?+ : jak chcesz
trafić sam nawias klamrowy, poprzedź go backslashem (i przedwias, i zawias,
o ile użyłeś obu)
No to pora na nawiasy kwadratowe [] i znaczek
| (symbol potoku,
[Shift+\]).
Znaczek | mówi, że ma zostać trafione albo to, co stoi przed nim, albo to, co
stoi za nim, tzn. łoś|m trafi
w łoś ma w swoim posiadaniu łom wyrazy
pierwszy i ostatni. Natomiast nawiasy kwadratowe trafiają jeden znaczek
z pewnej klasy. Te klasy definiuje się w taki sposób: zwykła literka lub
cyferka mówi o samej sobie, minus mówi o zakresie.
[a-c] z początkowego wyrażenia trafia na jeden ze
znaczków pomiędzy a i c (czyli a, b lub c). Żeby trafić sam minus, umieść go
albo na początku klasy, albo na końcu:
[-a-zAEIOUY] trafia minus, dowolną małą literę lub
dużą samogłoskę. Żeby trafić cokolwiek, tylko nie tą klasę, wstaw na początku
daszek ^:
[^aeiouyAEIOUY] trafia cokolwiek, tylko nie
samogłoskę. Żeby wpasować nawias kwadratowy (którykolwiek), umieść go w klasie
na początku albo na końcu. Jeśli nie chesz tworzyć całej klasy, po prostu
poprzedź go backslashem (podobnie znaczek potoku). Tak w ogóle, to jakikolwiek
znaczek traci swoje specjalne znaczenie, gdy zostanie poprzedzony backslashem.
I jeszcze trick: klasa wszystkich znaków drukowalnych (w tym spacji
i tabulacji) ma skrót: kropkę. Zatem .{3} pasuje
trzy dowolne znaki.
Co może cię jeszcze zainteresować, to nawiasy okrągłe
(). Domyślasz się, że zespalają one kilka
fragmentów wyrażenia regularnego w jedną całość:
(test)|(pies) szuka dowolnego z wyrazów
test i
pies, a (as)+
trafia ciągi as,
asas,
asasasasas i tym podobne. Oczywiście możesz
wewnątrz nawiasu wstawić dowolnie skomplikowane wyrażenie.
Ostatnie ciekawe są dolar $ i daszek
^ (tym razem nie w klasie). Dolar użyty na końcu
wyrażenia przyczepia je do końca linii, daszek na początku wyrażenia
przyczepia je do początku linii. Dzięki temu ^test
trafi tylko na te słowa test, które są na
początku linii, a już tych dalszych nie, a ^jedyny tekst
w linii$ trafi w zdanie jedyny tekst
w linii, które musi samo w linii.
Specyficzne dla poszczególnych programów jest traktowanie sekwencji
escape'owych, takich jak \n czy
\t. Czasem (vim,
ex) się tego używa, a czasem
(grep, sed) - nie. Najlepiej poczytaj dokumentację
i popróbuj sam. A po więcej informacji o wyrażeniach regularnych odsyłam do
dokumentacji grepa, perla, vima (tutaj
wbudowany help, nie manual) i czego tylko masz zamiar używać co obsługuje
wyrażenia regularne. Tylko że najprawdopodobniej dodatkowe sztuczki nie będą
działać gdzie indziej.
Słówko komentarza: W różnych programach korzystających z wyrażeń regularnych niekiedy backslashem włącza się specjalne traktowanie niektórych znaków specjalnych, np. w sedzie, vimie i grepie żeby trafiać jeden lub więcej znaków, trzeba wstawić \+ zamiast pojedynczego +, podobnie jak nawiasy klamrowe {}, zwykłe () czy znaczek potoku |. Musisz sam popróbować, co jest jak traktowane.