Perl-compatible regulární výrazy v PHP – praktické příklady

8. února 2005

Po úvodním (převážně teoretickém) článku je na čase si ukázat, že to skutečně funguje. Proto si tentokrát předvedeme, jak snadno můžeme zkontrolovat správný zápis telefonního čísla, hesla či URL.

Malé procvičení

V předchozím článku jsme probrali základní konstrukce regulárních výrazů. A protože často jeden příklad vydá za dva odstavce teorie, podívejme se nyní na několik praktických příkladů.

Příklad 1. – telefonní číslo

Kontrola českého telefonního čísla v národním či mezinárodním formátu může být provedena pomocí regulárního výrazu ^(\+420)? ?\d{3} ?\d{3} ?\d{3}$. Subvýraz (\+420) odpovídá české předvolbě, která je nepovinná (subvýraz je následován otazníkem). Za předvolbou je nepovinná mezera následovaná třemi trojicemi číslic, které mohou být odděleny mezerou. Výraz tedy předpokládá, že ten, kdo bude telefonní číslo zadávat, jej buď napíše vcelku nebo číslice seskupí po trojicích (což je jediná správná možnost u devíticiferného telefonního čísla).

Příklad 2. – heslo

Většina systémů, která používá přístup chráněný heslem, vyžaduje, aby heslo, které si uživatel může sám zvolit, odpovídalo určitým pravidlům. Řekněme, že heslo má být minimálně 6 a maximálně 10 znaků dlouhé a smí obsahovat pouze číslice a malá a velká písmena anglické abecedy (přičemž heslo nesmí začínat číslicí). Zadání vyhoví regulární výraz ^[a-zA-Z][0-9a-zA-Z]{5,9}$. Na začátku musí být jedno písmeno anglické abecedy za nímž musí následovat minimálně 5 a maximálně 9 dalších znaků, které jsou číslicí nebo písmenem anglické abecedy.

Příklad 3. – URL

Někdy je vhodné kontrolovat také URL zadávanou do formuláře (například v diskusním fóru). Regulárních výrazů řešících tento problém bychom mohli na internetu najít desítky (například na RegexLib.com). Podívejme se také na jeden takový výraz. Oproti předcházejícím dvěma příkladům bude tento o něco složitější. Regulárnímu výrazu ^(http|ftp)s?://[a-zA-Z0-9][a-zA-Z0-9\-.]+\.[a-zA-Z]{2,6}(/|$)[][\w.?~%#&@/'\\=+-]*$ odpovídá URL pro HTTP (respektive HTTPS) či FTP (resp. FTPS) protokol.

První subvýraz popisuje možné protokoly (HTTP či FTP). Následuje nepovinné s, které rozšiřuje povolené protokoly o HTTPS a FTPS. Za sekvencí :// následuje první znak domény (povoleny jsou pouze písmena a číslice). Druhý a další znak domény (kromě domény 1. řádu) smí kromě písmen a číslic obsahovat také pomlčku a tečku. Za posledním znakem domény 2. řádu musí následovat tečka a za ní doména prvního řádu (o délce 2 až 6 znaků). Doména 1. řádu smí být složena pouze z písmen. Vzhledem tomu, že před tečkou oddělující doménu 2. řádu od domény 1. řádu je povolena (ve skupině znaků [a-zA-Z0-9\-.]) také tečka, je třeba zajistit, aby tečku oddělující doménu 2. a 1. řádu algoritmus zpracovávající regulární výraz rozpoznal. Faktem je, že tato tečka je poslední tečkou v doménovém jméně a za doménovým jménem musí následovat buď lomítko nebo konec řetězce. Pravě těmto dvěma situacím odpovídá alternace v subvýrazu (/|$). Tím de facto část regulárního výrazu \.[a-zA-Z]{2,6} ukotvíme k prvnímu lomítku za doménovým jménem (respektive v druhém případě ukotvíme ke konci řetězce). Za subvýrazem (/|$) již pouze následuje skupina znaků povolených ve zbytku URL (následovaná kvantifikátorem *, který signalizuje nepovinnost jakéhokoli pokračování URL). Metaznaky ] a - jsou ve skupině znaků na takové pozici, že se nemůže uplatnit jejich speciální význam (viz předchozí článek) a nemusí jim proto předcházet zpětné lomítko.

Práce v PHP

Máme za sebou několik praktických ukázek regulárních výrazů a tak nezbývá, než si ukázat, jak pomocí PHP provedeme porovnání určitého řetězce (textu) s regulárním výrazem. Jednou z funkcí pro práci s Perl-compatible regulárnímu výrazy je preg_match(). Funkce má dva povinné parametry (od nepovinných parametrů zatím odhlédneme), a to regulární výraz a řetězec, který se má s regulárním výrazem porovnat.

Dříve, než se podíváme na ukázkový kód, musíme si říci o jedné velmi podstatné skutečnosti. Samotný regulární výraz musí být ohraničen oddělovači (delimiters). Jako oddělovač smí být použit (dle definice) libovolný nealfanumerický znak kromě zpětného lomítka (\). Nejběžněji se však používá obyčejné lomítko (/). V našich příkladech budeme používat právě tento oddělovač. Pokud regulární výraz samotný obsahuje lomítko (respektive obecně znak použitý jako oddělovač), musí lomítku předcházet znak \. Máme například regulární výraz popisující číselný zlomek ^\d+/\d+$. Pokud takový regulární výraz chceme použít jako parametr funkce preg_match(), musíme jej upravit na /^\d+\/\d+$/.

$re=“/^\d+\/\d+$/“; //regulární výraz
$str=“6/12″; //testovaný řetězec
if(preg_match($re,$str))
{
   echo „Řetězec ‚$str‘ vyhovuje regulárnímu výrazu.“;
}
else
{
   echo „Řetězec ‚$str‘ nevyhovuje regulárnímu výrazu nebo došlo k chybě.“;
};

Funkce preg_match() vrací 1 (pokud řetězec regulárnímu výrazu odpovídá), 0 (pokud řetězec regulárnímu výrazu neodpovídá) nebo FALSE (pokud došlo k chybě – například když regulární výraz má chybnou konstrukci).

Jednotlivé funkce (chování a parametry) pro práci s regulárními výrazy se mohou mírně lišit v závislosti na použité verzi PHP. Proto, pokud nebude uvedeno jinak, budu předpokládat nasazení na PHP 4.3.3 a vyšším. Detailní informace o chování a parametrech jednotlivých funkcí v různých verzích PHP naleznete v manuálu, konkrétně v sekci Regular Expression Functions (Perl-Compatible).

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

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

Další článek fo
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

1 komentář

  1. mv

    Lis 22, 2009 v 18:21

    A co telefonní číslo typu +420 123 11 22 33?

    Odpovědět

Napsat komentář

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