Regulární výrazy v PHP 2.

1. února 2001

V minulém článku jsme se seznámili s regulárními výrazy a představili si některé metaznaky. Dnes se podíváme na další metaznaky a třídy znaků. Popíšeme si také jednotlivé funkce, které se používají v kombinaci s regulárními výrazy. V závěru je popsán regulární výraz, který kontroluje platnost e-mailové adresy.

Někdy můžeme potřebovat vybrat jeden znak z několik znaků (množiny znaků). K tomu nám slouží metaznaky ‚[‚ a ‚]‘. Vše bude jasnější na příkladu.

Regulárnímu výrazu ‚[12345]0‘ vyhoví pouze řetězce obsahující 10, 20, 30, 40, 50 (tedy třeba řetězce 10, 100, nebo fs30000df). Chceme-li, aby výrazu vyhověly pouze řetězce 10, 20, 30 ,40 ,50, použijeme metaznaky popsané v minulém článku ‚^[12345]0$‘.

Výše uvedený výraz můžeme vyjádřit i ve tvaru ‚[1-5]0‘, kde ‚-‚ zastupuje všechny číslice ležící mezi 1 a 5. Podobně je tomu u písmen. Výrazu ‚[abcdef]‘ odpovídá výraz ‚[a-f]‘.

Výraz, kterému vyhoví jakákoli podoba jména Pavel (třeba pavel, PAVEL, nebo pAvEL), bude vypadat takto ‚[pP][aA][vV][eE][lL]‘.

Metaznaky ‚[ ]‘ mají ještě jednu variantu – ‚[^1-5]0‘. ‚^‘ způsobí jakousi negaci – výrazu vyhoví všechny řetězce, které neobsahují znaky uvedené v hranatých závorkách. V daném příkladě jsou to všechny řetězce, které neobsahují 10, 20, 30, 40, 50 (tedy např. 90, 80fd, ale i dsd6000ery).

Dalším metaznakem je ‚|‘, tento metaznak nám výraz rozdělí na několik podvýrazů. Řetězec pak tomuto výrazu vyhoví v případě, že obsahuje alespoň jeden podvýraz.

Regulárnímu výrazu ‚aa|bb|cc‘ vyhoví pouze řetězce obsahující aa nebo bb nebo cc. Např. dfsaagh, asbbwe, ale i aabbcc.

Jestliže chceme vyrobit výraz, kterému vyhoví řetězec obsahující zkratku dne v týdnu a přitom nebude záležet ne velikosti počátečního písmena, musíme použít kombinaci metaznaků ‚[‚ a ‚|‘.

Výše popsaný regulární výraz bude tedy vypadat takto: ‚[Pp]o|[Úú]t|[Ss]t|[Čč]t|[Pp]á|[Ss]o|[Nn]e‘.

Metaznaky ‚[[:<:]]‘ resp. ‚[[:>:]]‘ označují začátek resp. konec slova.

Výrazu ‚[[:<:]]Pavel[[:>:]]‘ vyhoví pouze řetězce obsahující slovo Pavel.

Při psaní regulárních výrazů můžeme používat i tzv. třídy znaků. Výraz ‚[[:třída:]]‘ představuje jeden znak z dané třídy.

Třída Popis
alnum alfanumerické znaky (písmena angl. abecedy + číslice)
alpha písmena anglické abecedy
blank mezera a tabulátor
cntrl řídící znaky
digit číslice
graph znaky mající grafické znázorněním
lower malá písmena anglické abecedy
print tisknutelné znaky
punct interpunkční a další znaky (zavináč, závorky, …)
space jakákoli mezera (mezera, tabulátor, nová řádka, nová stránka,…)
upper velká písmena anglické abecedy
xdigit číslice šetnáctkové soustavy

Regulárnímu výrazu ‚[[:digit:]]{2}‘ vyhoví řetězec obsahující dvoumístné číslo, tedy např. 54, ale i sdf78fd. Častěji však budeme potřebovat zjistit zda řetězec obsahuje osamostatněné číslo, poté použijeme výraz ‚[[:<:]][[:digit:]]{2}[[:>:]]‘. Tomu tedy vyhoví např. řetězce 54 nebo sdf 78 fd.

Funkce, které slouží ke zpracování regulárních výrazů

Split – rozdělí řetězec na části a uloží do pole

array Split(string regulární výraz, string řetězec, integer limit)

Funkce rozloží řetězec do pole po částech oddělených textem, který vyhovuje regulárnímu výrazu. Parametr limit (nepovinný) určuje max. počet částí, na které bude řetězec rozložen. Jestliže je limit menší než počet částí v řetězci, obsahuje poslední prvek pole celou zbývající část řetězce.

Následující skript rozdělí větu na jednotlivá slova, která uloží do pole. Použijeme třídu ‚blank‘ vyjadřující mezeru, ta se musí objevit alespoň jednou, proto je použit metaznak ‚+‘.

$text = „Nazdar ty programátore“;
$x = Split(„[[:blank:]]+“, $text);//rozdělí řetězec na jednotlivá slova a uloží do pole
echo $x[0];//vypíše „Nazdar“
echo $x[1];//vypíše „ty“
echo $x[2];//vypíše „programátore“

Ereg – zjistí, zda řetězec vyhovuje regulárnímu výrazu

integer EReg(string regulární výraz, string řetězec , array shody)

Funkce vrací true, pokud řetězec vyhovuje regulárnímu výrazu, jinak vrací false. Pokud použijeme parametr shody, uloží se do pole řetězce, které vyhovují jednotlivým podvýrazům regulárního výrazu (ty jsou ohraničeny kulatými závorkami). Do prvku pole shody s indexem 0 se uloží ta část řetězce, která vyhovuje celému regulárnímu výrazu.

$text = „Nazdar ty programátore“;
$a = Ereg(„(Nazdar) (ty) (programátore)“, $text, $x);
echo $x[0];//vypíše „Nazdar ty programátore“
echo $x[1];//vypíše „Nazdar“
echo $x[2];//vypíše „ty“
echo $x[3];//vypíše „Nazdar“

Ereg_Replace – nahradí řetězec podle regulárního výrazu

string EReg_Replace(string regulární výraz, string náhrada, string řetězec)

Funkce nahradí část řetězce, která vyhovuje regulárnímu výrazu řetězcem náhrada. V řetězci náhrada lze použít i metaznak ‚\\číslice‘, který určuje podvýraz regulárního výrazu. Metaznak ‚\\0‘ určuje celý řetězec vyhovující regulárnímu výrazu.

$text = „Nazdar ty programátore“;
$x = Ereg_Replace(„(Nazdar) (ty) (programátore)“, „Ahoj“, $text);
echo $x;//vypíše „Ahoj“
$y = Ereg_Replace(„(Nazdar) (ty) (programátore)“, „\\2 \\3 \\1“, $text);
echo $y;//vypíše „ty programátore Nazdar“
$z = Ereg_Replace(„(Nazdar) (ty) (programátore)“, „\\0“, $text);
echo $z;//vypíše „Nazdar ty programátore“

Další funkce EregI resp. EregI_Replace jsou totožné s Ereg resp. Ereg_Replace, s tím rozdílem, že při porovnávání neberou ohled na velikost písmen.

Ukázka – platnost e-mailové adresy

if (EregI("^[a-z0-9]+[a-z0-9\._-]*[a-z0-9]+@[a-z0-9]+[a-z0-9\._-]*[a-z0-9]+\.[a-z]{2,3}$", $adresa) && !EregI("\.{2,}", $adresa) && !EregI("_{2,}", $adresa) && !EregI("-{2,}", $adresa) ):
echo "Platná adresa";
else:
echo "Neplatná adresa";
endif;

V proměnné $adresa máme e-mailovou adresu (třeba získanou z nějakého formuláře) a pomocí funkce EregI zjišťujeme, zda adresa odpovídá regulárnímu výrazu. Definujme si ještě pojem speciální znaky, což budou tečka, pomlčka a podtržítko.

Na začátku adresy musí být jakékoli písmeno nebo číslice. Dále se mohou vyskytnout slova oddělená speciálním znakem a před zavináčem je opět pouze písmeno nebo číslice. Následuje zavináč a za ním se opakuje výraz ze začátku. Na konci musí být tečka a za ní doména, ze 2 nebo 3 písmen.

Na závěr vyřešíme drobné nedostatky, které ten dlouhý regulární výraz má. V adrese elektronické pošty se totiž nesmí opakovat speciální znak několikrát za sebou.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

2 komentářů

  1. pan Rod

    Led 2, 2011 v 19:30

    jsem prvním účastníkem, který přidává nový komentář. Tak dobrá, tedy., Mi to nevadí, Ať si jsem teda první

    Odpovědět
  2. Martin Fiala

    Led 16, 2020 v 19:47

    Online nástroj pro práci s regulárními výrazy je na http://retezce.jednoduse.cz/

    Odpovědět

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *