Co to vlastně jsou regulární výrazy? Regulární výrazy slouží k porovnání a zpracovaní textu. PHP podporuje syntaxi POSIX-Extended. V určitých případech podporuje i perlovskou syntaxi PCRE (Perl-Compatible Regular Expressions). Je třeba ale zkompilovat PCRE knihovnu. V tomto textu se budeme zabývat pouze POSIXovou syntaxí.
Regulární výrazy jsou velice vhodné například k ověření emailové adresy. Regulární vyraz je takový vyraz, kterému určitý text vyhovuje (true), nebo nevyhovuje (false). V praxi to znamená, ze například regulárnímu výrazu 234 vyhovuje text 1234, 2345, ale i například 9923477. Ač se to na první pohled nezdá, v PHP se s nimi setkáváme docela často. Velikou zbraní při sestavování regulárních výrazů jsou speciální znaky (tzv. metaznaky), tak se na ně v rychlosti podíváme. Ten, kdo se již s regulárními výrazy v PHP nebo v jiném jazyce setkal, může následující odstavce až po třídy jen tak projet, aby pochopil nuance ve specifikaci PHP, nebo i vynechat. Ostatním doporučuji přečíst si více v manuálu PHP nebo přímo v unixovém shellu (man regexp nebo regex).
Speciální znaky (metaznaky)
Speciální znaky nezastupují v regulárním výrazu žádné písmenko, nýbrž mají speciální význam. Speciální znak ^ zastupuje začátek textu, naproti tomu znak $ zastupuje konec textu ⇒ výrazu 123$ vyhoví například abc123, ale ne 123abc apod. Dalším speciálním znakem je . (tečka). Tečka může zastupovat jakýkoliv znak. Velice důležitým metaznakem je \ (značkovač). Ten vrací metaznaku za ním jeho původní význam. Pokud například potřebujete mít v regulárním výrazu znak $ ne ve významu konce textu, ale ve významu znaku dolaru, použijte \$. Jedno zpětné lomítko se tedy zapíše \\ . Důležitými znaky jsou i [[:<:]] a [[:>:]], které nahrazují začátek a konec slova.
Kvantifikátory
Kvantifikátory jsou dalšími důležitými metaznaky. Jsou to speciální znaky určující počet opakování. V PHP defaultně nastavenými kvantifikátory jsou * (hvězdička), ? (otazník) a + (plus). Hvězdička nám říká, že se podvýraz může opakovat 0-Xkrát. Otazník 0–1×. Plus znamená, že znak se musí vyskytovat alespoň jednou (1-Xkrát). Další kvantifikátor se nazývá minmax. Píše se do složených závorek {}, do kterých se píšou dva prvky (minimální a maximální počet opakování). Pokud nechceme zadávat maximální nebo minimální počet opakování, nemusíme :). {1,} znamená nejméně jednou (tedy to samé jako +), {,3} znamená maximálně 3× (0× ,1×, 2×, 3×). Pokud nechceme nechat žádnou toleranci, můžeme to zapsat jako {12} (= {12,12}).
Podvýrazy
Podvýrazy se píší do kulatých závorek a sdružují jednotlivé části textu dohromady. Typickým příkladem podvýrazu je například podvýraz (12). Pokud za ním použijeme kvantifikátor, aplikuje se na celý tento podvýraz. To znamená, že výrazu ^(12)+$ vyhoví řetězec 12, 1212 atd. Další důležitou pomůckou je speciální znak | (svislá čára). Má význam disjunkce, tedy programátorům velmi dobře známého OR nebo ||. Výrazu ^1|2|3$ tedy vyhoví řetězce 1, 2 nebo 3. Znak | můžeme používat i mezi podvýrazy. Výrazu ^((12)|(34))+$ vyhoví 12,34,12343412, ale ne 13. V tomto případě bychom museli použít ^((1|2)|(3|4))+$ , což můžeme zapsat jednodušeji jako ^(1|2|3|4)+$, a to ještě jednodušeji do hranatých závorek ^[1234]+$.
Třídy
Posledním prvkem POSIXových regulárních výrazů, o kterých si budeme dnes povídat, jsou třídy. Třídy jsou již skupiny znaků přednastavené autory PHP. Syntaxe je [[:/trida/:]] a popis jednotlivých tříd je zde:
alnum – Písmena anglické abecedy a desítkové číslice
alpha – Písmena anglické abecedy
lower – Malá písmena anglické abecedy
upper – Velká písmena anglické abecedy
digit – Desítková čísla
xdigit – Šestnáctková čísla
punct – Interpunkční znaménka
blank – Tabulátor a mezera
space – Prázdné znaky (mezi prázdné znaky se nepočítá \n – nový řádek)
cntrl – Řídící znaky (\n, \t apod.)
print – Tisknutelné znaky
graph – Tisknutelné znaky (bez mezery)
V praxi to znamená, že výrazu ^[[:xdigit:]]*$ vyhovuje jakékoliv šestnáctkové číslo (123, 13de8a, abc).
Tak a teď konečně trocha toho vzrušení :) Nakousneme, jak použít regulární výrazy v praxi na příkladu ověřování správnosti emailové adresy. K tomu použijeme PHP funkci EregI, která má tři parametry, ale dnes nám postačí pouze dva. První je maska (regulární vyraz), druhý text. V masce nebudeme jmenovat všechny domény prvního řádu. Postačí nám, že to budou 2–4 písmena anglické abecedy. Důvod je v tom, že neustále přibývá nových domén. Navíc nikdo nemá důvod se registrovat pod neplatným emailem, pokud není bezdůvodně nucen ho zadávat :) Pokud je povinen zadávat email a přitom není důvod (např. guestbook), tak je to vaše blbost :) A stejně napíše neexistující adresu jen s koncovkou cz :). Tato maska je pouze pro znázornění příkladu a není dokonalá (viz níže a druhý díl :) Koukněme se tedy na to, jak by měl ověřovací script vypadat
<?
# overeni spravnosti emailu v PHP - ROOT.cz
# skript predpoklada register_globals = on
# v konfiguracnich souborech php
# promenna s emailem je $email
// definujeme masku
$maska = '^([[:alnum:]]+)@([[:alnum:]]+)\.([[:alpha:]]{2,4})$';
// zda se vam, ze neco nesedi? :)
function overmail($a)
// definujeme funkci, do promenne $a se ulozi obsah $email
{
global $maska;
if (EregI($maska ,$a)) return "email ".$a." je platny";
// rika, ze mail je platny
else return "email ".$a." je neplatny :P";
// vraci chybu
}
// zavola funkci a vypise jako html stranku :)
echo "<html>\n<body>\n".overmail($email)."\n</body>\n</html>";
// zavola funkci a vypise stranku
?>
Jak se script chová, vidíme na obrázcích. Email se zadává do url
O všech možnostech, které nám servírují PHP funkce, a použití si povíme příště. Ale aby nebyla nuda, tak zkuste najít jeden (ne)nápadný, ale dost velký nedostatek v masce za domácí úkol :) Kdo to zjistí první, napíše do komentářů a zdůvodní proč, dostane hudlana :))
Linky:
PHP Manuál
PHP Manuál > Regulární výrazy POSIX-Extended
PHP Manuál > Regulární výrazy PCRE