You are on page 1of 14

Wstp do wyrae regularnych na

platformie .NET
v1.1

Miosz Orze

Celem artykuu jest zapoznanie Czytelnika z podstawowymi elementami skadni wyrae regularnych
oraz sposobami ich wykorzystania na platformie .NET. Postaram si zachci tych, ktrzy jeszcze nie
mieli do czynienia z tym tematem do poznania tego potnego narzdzia.

05.2007 (poprawki 07.2007)


Pierwsza wersja tego artykuu zostaa nagrodzona w konkursie CodeGuru.pl.
Prosz o informacje jeli zauwaysz jaki bd w tekcie artykuu lub doczonym do niego kodzie.
ommail@wp.pl morzel.net
Kopiowanie jest dopuszczalne wycznie w celach niekomercyjnych i przy zachowaniu niezmienionej
treci.

Czym s wyraenia regularne?


Wyraenia regularne (regex, RE) moemy traktowa jako jzyk, za pomoc ktrego da si precyzyjnie
okreli wzorzec wystpowania okrelonego cigu znakw w acuchu tekstowym.
Wyraenia regularne pozwalaj na efektywn ocen poprawnoci skadniowej tekstu, jego przeszukiwanie oraz przetwarzanie...

Po co nam wyraenia regularne?


Bardzo czsto pisane przez nas oprogramowanie musi w pewnym momencie wykona operacje zwizane z walidacj lub parsowaniem tekstu. Moe np. zaj konieczno sprawdzenia czy wpisany przez
uytkownika identyfikator ma prawidowy format albo wykonania sekwencji operacji w zalenoci od
danych znajdujcych si w pliku tekstowym o zoonej strukturze.
Chocia wyraenia regularne s obszernym zagadnieniem a ich skadnia nie wyglda zbyt zachcajco:
^[d-z]_\d{3}_(xyz|pki)_\d{2}_\w{2,7}.sql$, na pewno warto powici dzie nauki na opanowanie podstaw tego tematu. Istotne jest to, e elementarna wiedza na temat RE moe bardzo zwikszy
nasz produktywno! Poza tym wyraenia regularne s uniwersalne. W C#, Javie, Perlu, Pythonie itd.
wygldaj niemal tak samo. Moesz je nawet wykorzysta podczas zada nie zwizanych z programowaniem (np. do masowej zmiany nazw plikw).

Regex vs. metody z klas String oraz Char.


Klasy String i Char zawieraj mnstwo metod, ktre s przydatne przy przetwarzaniu tekstu. Jednak
w niektrych przypadkach ich zastosowanie nie jest zalecane. Przypumy na przykad, e zachodzi
konieczno sprawdzenia czy nazwa pliku pasuje do okrelonego wzorca. Mona to zrobi bez uycia
wyrae regularnych ale takie rozwizanie ma co najmniej cztery bardzo powane wady:
kod jest dugi,
kod jest nieczytelny,
kod jest podatny na bdy,
kod jest nieelastyczny.
Kod jest podatny na bdy poniewa czsto polega na odwoaniu do indeksw poszczeglnych znakw
w nazwie - w takim przypadku nie trudno o pomyk, za to ciko wykry taki bd.
Kod jest nieelastyczny poniewa nawet najmniejsza zmiana formatu nazwy moe wiza si z koniecznoci przerobienia caej metody sprawdzajcej jej poprawno! Gdy do sprawdzania nazwy uyjemy
regex wtedy zajdzie koniczno zmiany jednej linijki kodu lub nawet adnej. Wyraenie sprawdzajce
nazw moe by przecie adowane z wiersza polece albo pobierane z sieci. Moe by nawet tak, e
odpowiednie wyraenie dostarcza klient a my tylko piszemy aplikacj, ktra je wykorzystuje.

Skadnia wyrae regularnych.


Zapis wyrae regularnych jest bardzo bogaty. W tym artykule wymieni tylko jego podstawowe
elementy, ktrych opanowanie jest proste i daje due moliwoci. Przedstawione informacje bdzie
mona utrwali dziki wiczeniom, ktre umieciem ma kocu tekstu (podaj skadnie ju teraz by
Czytelnik mia moliwo zrozumienia co dzieje si w omawianych dalej przykadach uycia wyrae
regularnych w .NET).

Skadnia wyrae regularnych. Klasy znakw.


Za pomoc klas znakw mona okreli typ symbolu, ktry wyraenie regularne uzna za prawidowy
(pasujcy do wzorca).
.
[abc]

Kady znak z wyjtkiem \n. Jeli ustawiona


jest opcja Singleline kropka pasuje te do \n.
Dowolny znak ze wskazanego zbioru.

[^abc]

Dowolny znak prcz tych ze zbioru.

[a-z0-9]

Dowolny znak z zakresu a do z lub od 0 do 9.

\w
\W

Dowolny znak z klasy word (litera, cyfra,


podkrelnik).
Dowolny znak z poza klasy word.

\s

Dowolny znak z klasy white-space.

\S

Dowolny znak z poza klasy white-space.

\d

Dowolna cyfra dziesitna.

\D

Dowolny znak inny ni cyfra dziesitna

Skadnia wyrae regularnych. Asercje pozycjonowania.


Przy uyciu poniszych symboli mona wyznaczy miejsce w tekcie, w ktrym musi pojawi si dopasowanie (tekst pasujcy do wzorca okrelonego przez wyraenie).
^

$
\b
\B

Dopasowanie musi si pojawi na pocztku tekstu. Jeli


ustawiona jest opcja Multiline moe to by pocztek
linii.
Dopasowanie musi si pojawi na kocu tekstu. Jeli
ustawiona jest opcja Multiline moe to by koniec linii.*
Dopasowanie musi si znajdowa na pocztku lub kocu
sowa.
Dopasowanie nie moe si znajdowa na pocztku lub
kocu sowa.

* Jest z tym pewien problem (wyjani to w wiczeniach).

Skadnia wyrae regularnych. Powtrzenia.


Za pomoc tych kwantyfikatorw mona okreli ile razy ma wystpi dany znak (lub grupa znakw).
Symbol powtrzenia odnosi si do elementu, po ktrym nastpuje (do pierwszego po jego lewej stronie).
*
+

Zero lub wicej razy.


Jeden lub wicej razy.

Zero lub jeden raz.

{n}

Dokadnie n razy.

{n,}

Minimum n razy.

{n,m}

Minimum n maksimum m razy.

Skadnia wyrae regularnych. Greedy vs Lazy.


Przypumy, e stosujemy wyraenie \bb\w* do znalezienia sw, ktre zaczynaj si na liter b. Domylne zachowanie wyrae regularnych jest zachanne, tzn. wyraenie dopasuje jak najdusze sowo
pasujce do wzorca. Moemy to zmieni stosujc zamiast kwantyfikatora * jego leniw wersj: *?
Teraz wyraenie dopasuje jak najkrtsze sowo pasujce do wzorca. W tabelce znajduj si leniwe
wersje wczeniej przedstawionych kwantyfikatorw.
*?

Zero lub wicej razy (leniwy).

+?

Jeden lub wicej razy (leniwy).

??

Zero lub jeden raz (leniwy).

{n,}?

Minimum n razy (leniwy).

{n,m}?

Minimum n maksimum m razy (leniwy).

Skadnia wyrae regularnych. Inne kwestie.


Poniej przedstawiam kilka innych elementw skadni, ktre z pewnoci czsto si przydaj.
\
\0x20

Ukonik jest rwnie znakiem ucieczki. Tzn. likwiduje znaczenie


znakw specjalnych np. \. znaczy dosownie kropka.
Kod szesnastkowy znaku ASCII

\u0020

Kod szesnastkowy znaku Unicode.

Wszystko po tym znaku jest komentarzem.*

()

Nawiasy zwyke uywane s do grupowania symboli.

Pionowa kreska oznacza alternatyw.

* Zaley od ustawiania opcji (omwi to przy okazji wicze).


Nie martw si jeli nie jeste pewien znaczenia ktrego z przedstawionych elementw syntaktycznych. Wszystko stanie si jasne gdy troch powiczymy!

Regex vs metody z klas String oraz Char. Przykadowy program.


Przewag wykorzystania wyrae regularnych doskonale wida na przykadzie poniszego zadania (realny problem, z ktrym si zetknem).
Trzeba zbudowa program bdcy elementem instalatora, ktry wykonuje pewne operacje na bazie
danych. Aby wykona te operacje program musi uruchomi skrypty, ktre znajduj si w okrelonych
plikach. Problem w tym, e aplikacja nie moe uruchomi wszystkich plikw, ktre znajduj si w katalogu lecz jedynie te, ktrych nazwa ma okrelony format. Wywoanie tylko odpowiednich plikw ma
krytyczne znaczenie - jeli si pomylimy baza zostanie uszkodzona.
Nazwa plikw, ktre maj zosta wykonane ma taki schemat (case-insensitive):
d_123_xyz_99_data.sql
dokadnie jedna litera z wyjtkiem a, b oraz c,
dowolna liczba trzycyfrowa,
sowo xyz lub pki,
dowolna liczba dwucyfrowa,
dowolne sowo od dugoci od 2 do 7 znakw (brak spacji).
Jeli zastosujemy wyraenia regularne caa metoda sprawdzajca format nazwy ma jedn linijk kodu:
private bool CzyNazwaPoprawnaRegEx(string nazwa)
{
return Regex.IsMatch(nazwa, wzorzecTextBox.Text, RegexOptions.IgnoreCase);
}

Nazwa, ktr sprawdzamy jest podawana jako parametr, a jej format jest okrelany przez wyraenie
pobierane z komponentu TextBox. Znaczenie Regex.IsMatch() oraz RegexOptions.IgnoreCase omwi
dokadnie w dalszej czci artykuu. Pamitaj, e podawane przez uytkownika wyraenie moe by
nieprawidowe i wwczas generowany jest wyjtek (jest on jednak obsugiwany w innym punkcie kodu). Oto prawidowe wyraenie testujce nazw: ^[d-z]_\d{3}_(xyz|pki)_\d{2}_\w{2,7}.sql$
Dla porwnania metoda sprawdzajca poprawno nazwy bez zastosowania RE wyglda tak:
private bool CzyNazwaPoprawnaSadoMaso(string nazwa)
{
try
{
if (nazwa[0] == 'a' || nazwa[0] == 'b' || nazwa[0] == 'c' ||
!Char.IsLetter(nazwa[0]))
{
return false;
}
if (nazwa[1] != '_')
{
return false;
}
if (!Char.IsDigit(nazwa[2]) || !Char.IsDigit(nazwa[3]) ||
!Char.IsDigit(nazwa[4]))
{
return false;
}
if (nazwa[5] != '_')
{
return false;
}
if (nazwa.Substring(6, 3) != "xyz" && nazwa.Substring(6, 3) != "pki")

{
return false;
}
if (nazwa[9] != '_')
{
return false;
}
if (!Char.IsDigit(nazwa[10]) || !Char.IsDigit(nazwa[11]))
{
return false;
}
if (nazwa[12] != '_')
{
return false;
}
if (nazwa.IndexOf('.', 13) - 13 < 2 || nazwa.IndexOf('.', 13) - 13 > 7)
{
return false;
}
else
{
string s = nazwa.Substring(13, nazwa.IndexOf('.', 13) - 13);
foreach (char i in s)
{
if (!Char.IsLetter(i))
{
return false;
}
}
}
if (nazwa.Substring(nazwa.Length - 4) != ".sql")
{
return false;
}
}
catch
{
return false;
}
// Jeli wykonanie dojdzie do tego punktu mona przyj, ze nazwa jest
// prawidowa.
return true;
}

No c chyba jasno wida, e nie tdy droga?


Peny kod przykadowego programu (VS 2005) zawierajcy prosty interfejs i obszerne komentarze jest
zaczony do artykuu.

Wyraenia regularne w .NET.


Wyraenia regularne s czci biblioteki klas podstawowych. Typy, ktre je implementuj znajduj si
w przestrzeni nazw System.Text.RegularExpressions. Ich skadnia jest zgodna z t znan z Perl 5.
Najwaniejszym elementem obsugi RE w .NET jest klasa Regex. Mona wykorzystywa jej metody statyczne bd te utworzy egzemplarz tej klasy.
Wyraenie regularne przechowywane jest albo w postaci MSIL (jzyka poredniego maszyny wirtualnej), albo w postaci sekwencji wewntrznych instrukcji (domylnie), wwczas jest ono interpretowane
przez specjalny engine. By RE zostao skompilowane do MSIL a nastpnie w miar potrzeby skompilowane (JIT) do kodu natywnego naley uy opcji RegexOptions.Compiled. Uycie tej opcji zwiksza
szybko wykonywania ale za to zuywa wicej pamici - nawet wtedy gdy obiekt regex jest ju niepotrzebny pami jest nadal zajta (zwalniana jest dopiero przy usuwaniu caego kodu aplikacji). Mona

uywa prekompilowanych wyrae regularnych (zapisanych w DLL), to eliminuje konieczno kompilacji po uruchomieniu programu.
Poniewa celem artykuu jest zapoznanie Czytelnika z podstawami RE i zachcenie go do dalszej nauki
przedstawi jedynie najpotrzebniejsze elementy trzech najbardziej przydatnych klas: Regex, Match
oraz MatchCollection. Po peniejszy opis tych a take innych klas takich jak Group czy Capture odsyam
do dokumentacji .NET (opisuje te zagadnienia w przystpny sposb).
Zanim zaczniemy warto wspomnie o problemie zwanym plag backslashy. O co chodzi? W wyraeniach regularnych znak \ ma specjalne znaczenie. eby zlikwidowa to specjalne znaczenie naley ten
znak podwoi. Niestety w stringach w C# backslash te ma specjalne znaczenie. W celu pozbycia si
tego znaczenia naley ten znak... podwoi. W taki sposb by zapisa jeden backslash w wyraeniu
trzeba by uy w stringu a czterech! Na szczcie projektanci C# wprowadzili do jzyka stringi
dosowne. Aby zlikwidowa specjaln interpretacj znakw w acuchu wystarczy poprzedzi go znakiem @. Np. @"\n" nie oznacza wcale nowej linii tylko napis \n. Oczywicie jeli chcemy zapisa w
wyraeniu znak \ musimy go podwoi (tego wymaga bowiem skadnia wyrae regularnych). Napiszemy wic tak: @"\\", na pewno wyglda to lepiej ni zapis: "\\\\".

Wyraenia regularne w .NET. Klasa Regex.


Z klasy Regex moemy korzysta dziki jej metodom statycznym bd te przez utworzenie obiektu tej
klasy. Reprezentuje ona niezmienne wyraenie (po jego utworzeniu nie mona go ju przeksztaci).
Gdy wyraenia bdziemy uywa rzadko wygodnie jest skorzysta z metod statycznych. Jeli natomiast bdziemy je wykorzystywa czciej wtedy warto jest utworzy stosowny obiekt klasy Regex
(rwnie ze wzgldu na efektywno).
Przykad:
Uycie metody statycznej do sprawdzenia czy w stringu znajduje si sowo zaczynajce si na liter a.
Console.WriteLine(Regex.IsMatch("dom", @"\ba\w*")); // False

Przykad:
Uycie metody obiektu do sprawdzenia czy w stringu znajduje si sowo zaczynajce si na liter a.
Regex re = new Regex(@"\ba\w*");
Console.WriteLine(re.IsMatch("trawa agrest")); // True

Wyraenia regularne w .NET. Klasa Regex. Opcje.


Przy tworzeniu obiektu klasy Regex lub wykorzystywaniu jej metod statycznych mona skorzysta
z kilku opcji:
Compile
CultureInvariant

Sprawia, e wyraenie jest kompilowane do MSIL. (szybsze


dziaanie ale duszy start i duej zajmowana pami)
Okrela, e rnice midzy jzykami bd ignorowane.

ECMAScript

Okrela, zachowanie zgodne z ECMAScript. Uycie wraz z ni opcji


innych ni Compile, IgnoreCase lub Multiline spowoduje wyjtek.

ExplicitCapture

Okrela, e nienazwane nawiasy zachowuj si jak grupy nieprzechwytujce.


Sprawia, e wielko liter nie ma znaczenia.

IgnoreCase
IgnorePatternWhitespace

None

Eliminuje z wyraenia biae znaki i w ten sposb umoliwia zwikszenie czytelnoci oraz stosowanie # komentarzy
Sprawia, e ^ oraz $ odnosz si rwnie do pocztku i koca linii.*
Oznacza, e nie okrelono opcji.

RightToLeft

Sprawia, e przeszukiwanie obywa si od prawej do lewej strony.

Singleline

Okrela e . (kropka) pasuje take do znaku nowej linii \n.

Multiline

* Jest z tym pewien problem (wyjani to w wiczeniach).

W celu uycia opcji podajemy je jako parametr przy tworzeniu obiektu lub korzystaniu z metod statycznych.
Do poczenia kilku opcji stosujemy operator | (alternatywa bitowa).
Przykad:
Wykorzystanie opcji IgnoreCase i Multiline:
Regex re = new Regex(@"\ba\w*", RegexOptions.IgnoreCase | RegexOptions.Multiline);

Jak wida wszystkie opcje nale do wyliczenia RegexOptions.

Wyraenia regularne w .NET. Regex.Replace().


Jeli chcemy zastpi jakim tekstem wszystkie dopasowania do okrelonego wyraenia moemy skorzysta z metody Replace() klasy Regex.
Przykad:
Zastpienie sw zaczynajcych si na liter k sowem kotletem.
Console.WriteLine(Regex.Replace("Uderzy go kijem!", @"\bk\w*", "kotletem"));

Wynik:
Uderzy go kotletem!

Wyraenia regularne w .NET. Regex.Split().


Klasa String udostpnia praktyczn metod podziau tekstu wg jakiego znaku. Np. by uzyska czteroelementow tablic typu string zawierajc poszczeglne skadowe adresu IP mona wykorzysta taki
kod:
string[] ip = "127.0.0.1".Split('.');

Podobny efekt mona otrzyma korzystajc z metody Split() klasy Regex. W przypadku uycia tej metody tekst zostanie podzielony zgodnie z wystpieniem dopasowania.
Przykad:
Stworzenie tablicy, ktrej pierwszy element bdzie zawiera nazw zmiennej a drugi jej warto (zakadamy, e s one rozdzielone pascalowym operatorem przypisania wraz ze spacjami):
string[] s = Regex.Split("X := 1234", " := ");

Jeli zastosujemy wyraenie regularne, ktre moe dopasowa pusty tekst, wwczas w wyniku uycia
Regex.Split() otrzymamy tablic pojedynczych znakw. Stanie si tak dlatego, e pusty string moemy
odnale w kadym punkcie badanego acucha. Dodatkowo oprcz znakw, ktre wystpiy w badanym tekcie, na pocztku i na kocu tablicy wystpi pusty string.
Przykad:
Kod tworzcy picioelementow tablic:
string[] s = Regex.Split("123", "a*");

Wartoci w tej tablicy bd wyglda tak:


""
"1"
"2"
"3"
""

Wyraenia regularne w .NET. Klasa Match.


Klasa Match reprezentuje wynik dopasowania (dopasowanie to fragment badanego tekstu, ktry pasuje do okrelonego wzorca). W celu utworzenia obiektu tej klasy naley skorzysta z metody Match()
klasy Regex.
Przykad:
Zbadanie istnienia sowa zaczynajcego si na liter a:
Regex re = new Regex(@"\ba\w*");
Match m = re.Match("mysz agrest")

Za pomoc waciwoci Success moemy sprawdzi czy nastpio dopasowanie:


Console.WriteLine(m.Success); // True

Waciwo Value pozwala na uzyskanie tekstu dopasowania:


Console.WriteLine(m.Value); // agrest

Taki sam wynik da uycie m.ToString().


Przy uyciu Index moemy pobra miejsce, w ktrym zaczyna si dopasowanie (liczone od 0):
Console.WriteLine(m.Index); // 5

Uycie Length podaje dugo dopasowania:


Console.WriteLine(m.Length); // 6

Jeli w tekcie jest wicej ni jedno dopasowanie obiekt zwrcony przez RegEx.Match() odnosi si do
pierwszego z nich.

Wyraenia regularne w .NET. Klasa MatchCollection.


Klasa MatchCollection reprezentuje sekwencje dopasowa zwrcon przez metod Matches() klasy
Regex.
Przykad:
Wykorzystanie klasy MatchCollection do znalezienia wszystkich sw zaczynajcych si na liter a:
Regex re = new Regex(@"\ba\w*");
MatchCollection mc = re.Matches("mysz agrest ameba garnek tama analogia");
Console.WriteLine("Znaleziono: {0}", mc.Count);
foreach (Match i in mc)
{
Console.WriteLine("{0} {1} {2}", i, i.Length, i.Index);
}

Wynik:
Znaleziono: 3
agrest 6 5
ameba 5 12
analogia 8 30

Czy zawsze warto uywa wyrae regularnych?


Naley sobie uwiadomi, e wyraenia regularne nie nadaj si do wszystkich zada. wietnie sprawdzaj si w problemach, w ktrych istotna jest jedynie syntaktyka (skadnia). Jeli natomiast oprcz
tego jak wyglda tekst wane jest take co ten tekst oznacza (jego semantyka) warto uy innych
technik ni RE.

Dobrze wida to na przykadzie wyraenia, ktre sprawdza poprawno adresu IPv4:


^(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)\.(2[0-4]\d|25[0-5]|[01]
?\d\d?)\.(2[0-4]\d|25[0-5]|[01]?\d\d?)$
Prawda, e to troch nieporczne? Jego skomplikowanie zwizane jest z tym i warto kadej z czterech liczb musi by w przedziale 0..255.

Regex + String + Int. Przykadowy program.


Czasem warto pomyle o poczeniu wykorzystania wyrae regularnych wraz z metodami z takich
klas jak String, Int, Char...
O zaletach takiego rozwizania mona si przekona na podstawie przykadowego programu, ktry
sprawdza poprawno kropkowo-dziesitnego zapisu adresu IPv4 (np. ten adres jest dobry: 127.0.0.1,
ale ten ju nie: 122.256.0.0).
Ponisza metoda uywa Regex.IsMatch() do sprawdzenia czy podany tekst skada si z 4 liczb odzielonych kropkami. Jeli tak jest to przy uyciu adres.Split('.') uzyskujemy dostp do poszczeglnych skadowych adresu. Nastpnie sprawdzamy czy wartoci adnej skadowej nie przekracza 255. Nie sprawdzamy dolnej granicy poniewa uycie wyraenia regularnego upewnia nas, i midzy kropkami znajduj si cyfry (wic moe tam by min. 0).
private bool CzyAdresIPv4JestPoprawny(string adres)
{
bool adresOK = true;
if (Regex.IsMatch(adres, @"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"))
{
string[] iP = adres.Split('.');
if (int.Parse(iP[0]) > 255 || int.Parse(iP[1]) > 255 ||
int.Parse(iP[2]) > 255 || int.Parse(iP[3]) > 255)
{
adresOK = false;
}
}
else
{
adresOK = false;
}
return adresOK;
}

Peny kod programu (VS 2005) jest zaczony do artykuu.


Oczywicie skoro kto zada sobie trud stworzenia i opublikowania wyraenia sprawdzajcego adres IP
nic nie stoi na przeszkodzie by je po prostu skopiowa. W tym przykadzie jednak chodzio mi o ukazanie tego, e RE nie nadaj si zbytnio do sprawdzania jak warto ma fragment tekstu.

wiczenia.
Nie mona nauczy si wyrae regularnych przez samo patrzenie na ich pogmatwan skadnie. Naley
nieco potrenowa. Do wicze wykorzystamy darmowy program Rad Software Regular Expression Designer 1.2 (wymaga NET 1.1). Mona te skorzysta z darmowego The Regulatora lub sharewareowego Expresso.
Program mona pobra z tej strony: http://www.radsoftware.com.au/regexdesigner
Regular Expression Designer jest bardzo prosty w obsudze, nie zaszkodzi jednak may opis tego do
czego su poszczeglne okna.

1 - W to okno wpisujemy tekst, na ktrym bdziemy testowa wyraenie regularne.


2 - Tutaj wpisujemy wyraenie.
3 - W tym oknie wpisujemy (opcjonalnie) tekst, ktry zostanie wstawiony do wejciowego tekstu
w miejscu dopasowania.
4 - Tutaj moemy zobaczy rezultat zastpienia.
5 - W tym oknie moemy ustawi opcje wyraenia regularnego.
6 - Tu moemy zobaczy rezultaty dopasowania.
7 - W tym oknie widzimy elementy skadniowe, ktre moemy uy w wyraeniu.
8 - Gdy zaznaczymy jaki element skadniowy, w tym miejscu pojawi jego si jago szerszy opis.
Aby uruchomi sprawdzanie tekstu naciskamy przycisk z zielon strzak (lub klawisz F5).
Uwaga!
Podczas kopiowania zamieszczonych tu przykadw wyrae regularnych uwaaj by wraz z nimi nie
skopiowa niepotrzebnych biaych znakw...
wiczenie 1.
Tekst:
Duy dom.
Stefan jest domniemanym sprawc tego czynu.
DOM (Document Object Model)
1.1
Wyraenie: dom
Chocia moe to si wydawa dziwne, sowo dom jest w 100% poprawnym regex! Dopasowuje ono
dokadnie cig symboli dom (lub jak jego odmian jeli ustawimy ignorowanie wielkoci liter). Tak
wic w zalenoci od opcji IgnoreCase powiniene otrzyma 2 lub 3 dopasowania (zaznacz dowolne
z nich eby zobaczy, w ktrym miejscu tekstu ono wystpio).

1.2
Zauwa, e dom dopasowuje rwnie tekst bdcy czci sowa domniemanym. Aby wyraenie akceptowao jedynie dom bdcy osobnym sowem naley zmieni nieco wyraenie przez uycie asercji \b,
ktra oznacza koniec lub pocztek sowa.
Wyraenie: \bdom\b
Teraz cig znakw w sowie domniemanym si nie zaapa.
wiczenie 2.
Tekst:
a\aplikacja
a10 a_x
Afganistan
bilon
kompilator
2.1
Wyraenie: a.
Takie wyraenie dopasuje kady cig symboli skadajcy si z litery a, po ktrej nastpuje dowolny
symbol. Kropka oznacza cokolwiek z wyjtkiem znaku nowej linii lub wszystko bez wyjtku (jeli ustawiona jest opcja Singleline).
2.2
Wyraenie: a.*
Tym razem na kocu wyraenia jest gwiazdka, ktra mwi, e dowolny znak (wyznaczony przez kropk) moe powtrzy si zero lub wicej razy.
2.3
Wyraenie: a\d+
Teraz jedyne dopasowanie to a10. Dlaczego? Poniewa po literze a ma wystpi co najmniej jedna
cyfra.
2.4
Wyraenie: a\d*
Wystarczy, e zmienimy kwantyfikator + (jeden lub wicej razy) na * (zero lub wicej razy) a wynik
dopasowania jest diametralnie inny. Tym razem zaapi si wszystkie pojedyncze litery a oraz cig
a10.
wiczenie 3.
Tekst:
00_233 00-999 34-700 34-99d 433-234
3.1
Wyraenie: \d{2}-\d{3}
To wyraenie sprawdza poprawno kodu pocztowego. Szuka dwch cyfr, potem rednika a na koniec
znowu trzech cyfr. Czy jednak na pewno to regex dziaa jak naley?
3.2
Wyraenie: \b\d{2}-\d{3}\b
Poprzednia regua miaa istoty bd. Akceptowaa te cze tekstu 433-234. Dziki uyciu \b na pocztku i na kocu wyraenia likwidujemy ten problem.
wiczenie 4.
Tekst:
14.12.1924 Jan Kowalski
02.01.1999 Stefan mietana

24.10.1938 Pawe Nowak


04.09.2002 Anna Kotlet
30.08.2006 Henryk Ziemniak
4.1
Wyraenie: .{6}19.*
Za pomoc tej reguy moemy znale wszystkie osoby urodzone w latach 1900..1999. Jak to dziaa?
Najpierw moe wystpi sze dowolnych znakw a potem ma wystpi cig 19 po ktrym moe by
dowolny tekst. Zauwa, e (w okienku z dopasowaniami) na kocu kadego nazwiska wida kwadracik.
Pojawia si on dlatego, e kropka pasuje rwnie do \r (carriage return).
4.2
Wyraenie: .{6}19[\w ]*
Tym razem brzydki kwadracik znik. Dlaczego? Poniewa teraz stwierdzamy, e po cigu 19 ma wystpi znak nalecy do klasy word (litera, cyfra lub podkrelnik) albo spacja. Zauwa, e spacja podana
w nawiasach prostoktnych jest rozumiana jako spacja niezalenie od ustawienia opcji IgnorePatternWhitespace.
wiczenie 5.
Tekst:
ananas banan gra proces atv bbc exe
5.1
Wyraenie: [ab]..
Ta regua okrela cig trzech symboli, z ktrych pierwszy jest albo liter a albo liter b, kolejne dwa
symbole s dowolne.
5.2
Wyraenie: [^ab]..
Tym razem szukamy cigu trzech symboli, takiego, e pierwszy symbol nie jest ani liter a ani liter b.
wiczenie 6.
Tekst:
ananas banan gra proces atv bbc execement dom
traktor 24h 74lata
6.1
Wyraenie: \b[a-d]\w*
Dziki tej regule znajdziemy wszystkie sowa zaczynajce si na liter a, b, c lub d. Zauwa, e rednik
gdy jest wewntrz nawiasw prostoktnych zachowuje si jak operator zakresu. Zwr take uwag,
e na kocu wyraenia nie umieciem \b. Nie trzeba tego robi poniewa \w nie zaakceptuje spacji
(ktra przecie rozdziela sowa).
6.2
Wyraenie: \b[a-d0-5]\w*
Tym razem szukamy sw, ktre zaczynaj si na a, b, c, d, 0, 1, 2, 3, 4, lub 5.
wiczenie 7.
Tekst:
anakonda ma nos jak antena
7.1
Wyraenie: ana?
Otrzymalimy dwa dopasowania (ana, an). Stao si tak poniewa ? oznacza, e poprzedzajca go litera a moe pojawi si dokadnie raz lub ani razu.

7.2
Wyraenie: a(na)?
Umieszczajc cig na w nawiasach okrelamy, e cay cig na moe wystpi zero lub jeden raz.
Podobnie moemy uy nawiasw z kadym innym kwantyfikatorem, np. z * Jeli nie masz wczonej
opcji ExplicitCapture w oknie z dopasowaniami pojawiy si elementy z klas Group i Capture (ich omwienie wykracza poza ramy tego artykuu).
wiczenie 8.
Tekst:
sysdm.cpl
examplefile.html
boot.ini
services.msc
8.1
Wyraenie: \b\w{1,8}\.\w{3}\b
Za pomoc tej reguy sprawdzamy czy nazwa ma format 8.3. Najpierw oznaczamy, e ma wystpi od
1 do 8 znakw z klasy word (z ktrych pierwszy znajduje si na granicy sowa). Potem ma wystpi
kropka (dosownie kropka wic poprzedzilimy j znakiem ucieczki \). Na koniec maj wystpi dokadnie 3 znaki z klasy word.
8.2
Wyraenie:
\b # granica slowa
\w{1,8} # od 1 do 8 znakow
\. # kropka
\w{3} # 3 znaki
\b # granica slowa
Aby mc skorzysta z takiej formy wyraenia regularnego musisz ustawi opcj IgnorePatternWhitespace. Jej ogromn zalet jest to, e moemy tworzy komentarze przy uyciu znaku #.
wiczenie 9.
Tekst:
kot dom kotwica domowa
GetPrice
9.1
Wyraenie: kot|dom
Ta regua dopasowuje wszystkie wystpienia cigu kot lub dom.
9.2
Wyraenie: \b(kot|dom)\b
Za pomoc tego wyraenie znajdziemy wszystkie sowa kot lub dom. W odrnieniu od punktu 9.1
cze kot w sowie kotwica nie zostanie dopasowana. Koniecznie sprawd jak zmieni si dziaanie wyraenia po usuniciu nawiasw.
9.3
Wyraenie: Get|GetPrice
Tym razem jedyne dopasowanie to Get.
9.4
Wyraenie: GetPrice|Get
Ta regua zwraca rwnie jedno dopasowanie, ale tym razem jest to cig GetPrice. Wniosek? Kolejno
elementw w alternatywie ma znaczenie! Wyraenie regularne przestaje szuka kolejnego dopasowania gdy znajdzie ju dopasowanie do jakiego czonu alternatywy.

wiczenie 10.
Tekst:
babaa barka banan
10.1
Wyraenie: b\w+
Zastosowalimy zachann wersj kwantyfikatora + wic wyraenie szuka najduszego moliwego dopasowania.
10.2
Wyraenie: b\w+?
Tym razem zmienilimy kwantyfikator na leniwy wic wyraenie dopasuje jak najkrtszy tekst, ktry
pasuje do wzorca (w tym przypadku bdzie to litera b i jeden znak z klasy word).
wiczenie 11.
Tekst:
to chyba
jest jaka
szansa
11.1
Wyraenie: \b\w*\w$
Jeli mamy wyczon opcje Multiline powinno zosta dopasowane jedynie sowo: szansa. Jest tak dlatego, e symbol $ oznacza w tym przypadku koniec tekstu. Co si zmieni gdy ustawimy opcje Multiline? Niestety nic! Jeli masz zainstalowanego Pythona sprbuj jak zadziaa to z programem redemo.py
(jest doczany przy standardowej instalacji w katalogu Tools\Scripts). Ustaw opcje Multiline oraz zaznacz opcje Highlight all matches i przekonaj si, e zostay znalezione trzy dopasowania: chyba, jaka
oraz szansa.
11.2
Wyraenie: \b\w*[\w\r]$
Ustawiamy opcje Mutiline - tym razem udao si nam dopasowa sowa chyba, jaka oraz szansa. Stao
si tak dlatego, e teraz na kocu linii moe znajdowa si znak z klasy word albo znak \r (carriage
return).

Podsumowanie.
Wyraenia regularne s potnym narzdziem, ktre w wielu przypadkach pozwala na tworzenie elastycznego, klarownego i efektywnego kodu. Nie kady programista .NET musi by znawc tego zoonego tematu, ale kady powinien chocia rozumie podstawy ich skadni i sposobu wykorzystania na
platformie .NET Framework. Jeli chcesz zaoszczdzi sobie w przyszoci wiele czasu i nerww zainwestuj jeden lub dwa dni na opanowanie tych podstaw - z pewnoci nie poaujesz!
Jeli masz troch wicej czasu i chci poszerz swoj wiedz na temat RE - zwr szczegln uwag na
takie elementy jak konstrukcje grupujce, wzory zastpowania czy odwoania wstecz...
Kod doczony do artykuu mona pobra z tego adresu:
http://morzel.net/edu/wdre/wdre_src.zip

You might also like