Regulárne výrazy

Porovnanie :: PHP | Python

Regulárne výrazy sú veľmi mocným nástrojom slúžiacim pre prácu s textovými údajmi. Je to vzor, ktorý umožňuje popísať obsah reťazca. Hovorí nám, čo sa môže a čo sa nesmie v reťazci vyskytovať, aký je možný počet výskytov týchto opakovaní, na akej pozícii sa má daný znak nachádzať a pod.

Sám o sebe nemá regulárny výraz zmysel. Zmysel nadobúda až pri porovnávaní s konkrétnym reťazcom. Výsledok, ktorý dosiahneme porovnávaním reťazca a regulárneho výrazu, je informácia, čí daný reťazec zodpovedá alebo nezodpovedá vzoru (regulárnemu výrazu).

Jednoduché vzory

Vzor je reťazec, ktorý popisuje štruktúru a obsah iného reťazca. Väčšina znakov použitelná v regulárnych výrazoch zodpovedá sama sebe.

/Perl/

Predchádzajúci príklad nám zobrazuje jednoduchý vzor, kde znaky daného reťazca zodpovedajú sami sebe.

Avšak existujú aj znaky, ktoré majú zvláštny význam (viac v kapitole Metaznaky).

Metaznaky

Niektoré znaky použité v regulárnom výraze nezodpovedajú sami sebe, ale majú špeciálny význam - reprezentujú iné znaky, alebo upresňujú ďalšie vlastnosti časti reťazca.

Ak majú špeciálny význam, hovoríme o tzv. metaznakoch.

Ak chceme aby vzor obsahoval niektorý metaznak, tak musíme pred neho napísať znak obráteného lomítka. Tým dochádza k potlačeniu jeho špeciálneho významu. Nasledujúca tabuľka zobrazuje metaznaky použitelné v regulárnych výrazoch.

Znak Význam
\ Potlačuje metacharakter nasledujúceho znaku, alebo s nasledujúcim znakom tvorí tzv. metasymbol
| Oddeľuje možné varianty
( ) Znaky vo vnútri zoskupuje do jednej skupiny
^ Začiatok reťazca alebo začiatok riadku
$ Koniec reťazca alebo pozícia pred začiatkom riadku
[ Začiatok triedy znakov
. Akýkoľvek jeden znak (okrem znaku konca riadku \n)
* Výskyt predchádzajúceho symbolu 0 alebo viackrát
+ Výskyt predchádzajúceho symbolu 1 alebo viackrát
? Výskyt predchádzajúceho symbolu 0 alebo 1 krát
{ Začiatok určenia počtu opakovaní pre výskyt predchádzajúceho symbolu

a.b # a, akýkoľvek znak, b
   a1b, a+b # príklad výpisu

^abc # reťazec začína písmenami abc
   abcdefg, abc321 # príklad výpisu

abc$ # reťazec končí písmenami abc
   defgabc, 321abc # príklad výpisu

Triedy znakov

Triedu znakov môžeme považovať za metasymbol, pomocou ktorého sa dá popísať určitá skupina znakov.

Túto triedu môžeme popísať buď výberom znakov alebo triedou znakov jazyka Perl.

Výber znakov Význam Trieda znakov Perl
[0-9] Čísla 0 až 9 \d
[^0-9] Všetko ostatné okrem číslic \D
[ \f\n\r\t] Prázdny znak \s
[^ \f\n\r\t] Neprázdny znak \S
[a-zA-Z0-9] Alfanumerický znak \w
[^a-zA-Z0-9] Nealfanumerický znak \W

Kvantifikátory

Kvantifikátory sú symboly pomocou ktorých môžeme špecifikovať počet a opakovanie sa určitého znaku či skupiny znakov. Výhoda kvantifikátorov je v tom, že nemusíme výskyt určitého znaku explicitne uvádzať viackrát.

Kvantifikátor Význam
* 0 alebo viac výskytov predchádzajúceho znaku
+ 1 alebo viac výskytov predchádzajúceho znaku
? 0 alebo 1 výskyt predchádzajúceho znaku
{POČET} výskyt predchádzajúceho znaku presne POČET-krát
{MIN,} výskyt predchádzajúceho znaku aspoň MIN-krát
{MIN, MAX} výskyt predchádzajúceho znaku aspoň MIN-krát a najviac MAX-krát

Kvantifikátory sa vzťahujú vždy bezprostredne k predchádzajúcemu znaku alebo triede znakov. Ak chceme aby sa vzťahovali k viacerým znakom, je potrebné tieto znaky zoskupiť pomocou okrúhlych zátvoriek.

/abc*/ # zodpovedá reťazcu ab, abc, abcc, abccc, atď.
/a(bc)*/ # zodpovedá reťazcu a, abc, abcbc, abcbcbc, atď.
/ab+c/ # zodpovedá reťazcu abc, abbc, abbbc, atď.
/ab?c/ # zodpovedá reťazcu ac, abc
/ab{3}c/ # zodpovedá reťazcu abbbc
/ab{3,}c/ # zodpovedá reťazcu abbbc, abbbbc, abbbbbc, atď.
/ab{3,5}c/ # zodpovedá reťazcu abbbc, abbbbc, abbbbbc

Nasledujúci príklad nám zobrazí ako pomocou regulárneho výrazu skontrolovať, či PSČ je napísané v správnom tvare. Za správny tvar považujeme tvar xxx medzera xx.

/^[0-9]{3}\s[0-9]{2}$/ # reťazec bude napísaný v tvare xxx xx, akceptujú sa len čísla nie písmená

# ^[0-9]{3} - reťazec začína práve tromi číslami z množiny čísel 0 až 9
# \s - nasleduje prázdny znak
# [0-9]{2}$ - reťazec končí práve dvoma číslami z množiny čísel 0 až 9

Ďalší príklad nám demonštruje kontrolu 3-ciferného čísla.

print "Zadaj trojciferné číslo: ";
$cislo = <STDIN>;
if ($cislo =~ /^[1-9]\d{2}$/) # tento zápis kontroluje, či číslo je naozaj 3-ciferné /^[1-9]\d{2}$/
{
  print "OK\n";
}
else
{
  die "Chyba! Toto nie je trojciferné číslo!\n";
}

Porovnávacie príklady

Nahradzovanie reťazcov

Nahradzovanie reťazcov je veľmi rozšírený nástroj a je potrebný takmer v každom skripte.

Príklad:

$text = "slovo2"; # v premennej text je uložený reťazec slovo2
print $text; # vypíše sa text slovo2

$text =~ s/slovo1/slovo2/; # slovo1 nahradí slovo2
print $text; # vypíše sa text slovo1

Pri nahradzovaní sa používa predpona s. Na výmenu všetkých nájdených slov sa používa parameter g (global).

Príklad:

$text = 'riby korito jazero';
print $text; # vypíše sa riby korito jazero

$text =~ s/ri/ry/g; # reťazec ri nahradí všetky nájdené reťazce ry
print $text; # vypíše sa ryby koryto jazero

Porovnávacie príklady