Regulární výrazy II

Napsal O webu (») 6. 4. 2006 v kategorii Programování, přečteno: 2835×

Příklady, praktické ukázky

Minule jsme si ukázali základní syntaxi a jednoduché příklady, teď už se podíváme na trochu složitější příklad

<Nějaký TAG\b[^>]*>(.*?)</Nějaký TAG>

Je to zápis, kterému vyhovuje otevření a uzavření specifického tagu "Nějaký TAG". Pomocí závorek si budeme pamatovat obsah v tomto tagu. Pokud je nám jedno co uvnitř něj bude, postačí nám již známá tečka. Malé omezení tento zápis přece jen má a to je to, že nerozpozná vnořené tagy do sebe, např.:
<Nějaký TAG>první<Nějaký TAG>druhý</Nějaký TAG>konec prvního</Nějaký TAG>a tenhle už nepatří nikam

navíc v proměnné bude uloženo "první<TAG>druhý" což může působit problémy. To se dá vyřešit poměrně složitější konstrukcí, kdy si budeme pamatovat počet otevřených a zavřených tagů pomocí zásobníku, což ovšem překračuje rámec tohoto miniseriálu :)
Ukážeme si ale navíc ještě, jak parsování vyřešit pro obecný tag.

<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)</\1>

Zápis je malinko zavádějící, protože povoluje pouze tagy velkým písmem. Rovněž je zde poprvé ukázáno, jak se přistupuje k zapamatovaným částem v kulatých závorkách. Slouží k tomu jednoduše číslo udávající pozici kulatých závorek v rámci zápisu.

Tj.: (prvni)(druha)(treti)....\1\2\3. Samozřejmě nesmíte zapomenout použít zpětné lomítko :)


Takovéto a další parsování textu se může hodit zejména tehdy, chcete-li například optimalizovat Vaše stránky pro mobilní telefon, nebo jiné PDA zařízení, u kterého předpokládáte pomalou linku připojení. Takže můžete z Vašich stránek odstranit veškeré zbytečné mezery, konce řádků, tabulátory, ... a další nepotřebné věci. Statisticky sice tyto znaky zabírají méně než 5% datového toku (u kvalitních stránek) ale i tímto malým zrychlením můžete uživatele potěšit.


Teď si ukážeme pár užitečných příkladů:


Jak na e-mail?
Kompletní ošetření korektnosti e-mailu je poměrně složitá záležitost a úplný regulární výraz řešící tento problém má dost hodně řádků (pokud to někoho opravdu zajímá, může se podívat na příslušné RFC0822 na stránce http://www.ietf.org/rfc/rfc0822.txt) Dal jsem si tu práci a podíval se na to jak vypadá celý regulární výraz. Musím říct, že vysvětlovat, nebo dokonce jen ho pochopit bych nikomu nepřál. Pro zvědavce je uveden na konci tohoto článku. Nám však postačí řekněme částečné, ale dostatečné oveření :).

\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b

Z lenivosti je to zase pouze pro velká písmena. Pokud ne/chcete například pouze určité subdomény, není nic jednoduššího, než je tam přidat.
^[A-Z0-9._%-]+@[A-Z0-9.-]+\.(?:[A-Z]{2}|com|org|net|biz|info|name|aero|biz|info|jobs|museum|name)$


Ach ty datumy

Datum může být zapeklitější než se na první pohled zdá. Nejen, že musíte brát v ůvahu různé formátování a oddělení, ale také různé počty dnů v měsíci, atp.
(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d

Tento regulární výraz to částečně řeší. Jak jste asi postřehli, je pro formát dd-mm-yyyy používaný v ČR.


Snad poslední příklad, který když pochopíte, tak budete vědět potřebné minimum pro pohodlné používání regulárních výrazů.


Emulace "near".
Na první pohled se to může jevit složitě, ale skutečně to příliš složité není. Stačí si uvědomit, že hledáte "slovo" něco něco něco "jiné slovo" Takže vlastně hledáte pouze konkrétní dvě slova s nějakou zbytečnou mezerou mezi nimi.
\bSlovo\W+(?:\w+\W+){1,6}jineslovo\b


Kvantifikátor počtu opakování "{1,6}" určuje kolik slov může být mezi hledanými výrazy, tj. konkrétně šest slov mezi.


Pokud se nyní podíváte např. v PHP do manuálu, najdete perfektní funkci preg_replace(). Je to možná nejlepší fce na použití regulárních výrazů a nahrazování v PHP. Ne možná, ona je :). O jejím použití se v manuálu dočtete dost, takže snad jen ve zkratce:


$vzory = array('regul_vraz_1','regul_vraz_2','regul_vraz_X');

$nahrad = array('vysledek_1','vysledek_2','vysledek_X');

$mujtext = preg_replace( $vzory, $nahrad, $mujtext);




V tomto textu jsem popsal základ použití regulárních výrazů. K jejich úplnému pochopení to jistě stačí, ale pokud je chcete používat na opravdu profesionální úrovni (např. pro silný textový manipulátor awk) je dobré si projít další příručky, nebo manuály, ve kterých se dá najít spousta dobrých vychytávek.


A nyní slíbený, podle mě celkem šílený:


regulární výraz pro úplné ověření emailu



(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:

(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.

|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t]

)*(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=

[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(

?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \

x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\

[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])

*(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[

\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*

))*|(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(

?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*

"(?:(?:\r\n)?[ \t])*)*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".

\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\

]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?

[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\

Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[

\t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x1F

]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]

\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()

<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@

,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?

:(?:\r\n)?[ \t])*)?(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\

n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?

:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[

^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()

<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\

r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x

1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[

\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^

()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<

>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(

?:(?:\r\n)?[ \t])*)|(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r

\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(

?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:

(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\

["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:

(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \

x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"

(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:

(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?

[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(

?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x

00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[

([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".\[\]

\x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))

|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\<(

?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:

\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*

\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\

[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]

]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)

?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|

\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?

[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x1F]

+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\

r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^(

)<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>

@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\

n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x

1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\

"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\

n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])

+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n

)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x1

F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\

]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s

*(?:(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(

?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*

"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[

\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]

))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*

@(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r

\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\]

(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\

] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]])

)|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()<>@,;:\\".

\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\

]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)

*\<(?:(?:\r\n)?[ \t])*(?:@(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?

:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\

\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\

\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".

\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\

r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t

])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r

\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\

x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\

[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?

:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["

()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?

:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x0

0-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?

:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?

:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00-\x1F]+(?:(?:(?:\r\n)?[

\t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:

\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()<>@,;:\\".\[\] \x00

-\x1F]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([

^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*))*

)?;\s*)


K tomuhle se nedá snad ani nic říct. Možná by se hodil jen citát: Není nic těžšího než vyjádřit významnou myšlenku tak, aby jí každý rozuměl. Arthur Schopenhauer. Kdyby pan Schopenhauer viděl toto, měl by ze své myšlenky určitě radost.

Autor: mimi
Facebook Twitter Topčlánky.cz Linkuj.cz

Komentáře

BYZI z IP 193.179.202.*** | 6.4.2006 14:15
LOL, ten email je drsny, asi zkusim..., jinak ja pouzivam tohle...

if (eregi("^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$", $email)) {
 echo "email je validni";
}
smajl
*** M I Z U *** z IP 213.81.194.*** | 6.4.2006 18:02
[1]toto nie je najlepsi napad na kontrolu mailu. nuti to uzivatela zapisovat zavinac,mal by si povolit aj moznost (at) alebo (zavinac) alebo nieco podobne,takto dobre nahravas spamovym robotom
BYZI z IP 193.179.202.*** | 6.4.2006 18:26
Spam roboti by museli nejprve prelousknou registrace>prihlaseni... A pokud myslis nejakou free diskusi, tak tam nejsou zadna data povinna..., takze ti to nepomuze proti SPAMu...smajl
*** M I Z U *** z IP 213.81.194.*** | 6.4.2006 18:41
ako ktori,kazdy robot pracuje inak,su rozne typy. su aj roboti,ktori proste oddchytavaju post,get posielane na serer a v tom hladaju zavinace...
BYZI z IP 193.179.202.*** | 8.4.2006 19:57
No pokud odchytavaji POST tak jsme vseci stejne v prdeli, pokud nepouzivas https..., bo HTTP protokol neni nijak sifrovany, takze diky POST odchyti vse..., a pokud je uz nejaky robot v praxi pouzivan, tak tam je i alternativa na @ [at, zavinac atd...], ale dobry napad to alespon nejak stizit...
host z IP 158.196.68.*** | 13.4.2006 22:18
Pridat tam treba (at) a tak neni asi zadny problem, ale proti spamu vydim jako jedinou ochranu \"opis obrazek\"... Ikdyz me to nekdy uz taky stve, ale co jineho se da delat?
*** M I Z U *** z IP 213.160.171.*** | 13.4.2006 22:23
[6] Sorry,ale mi sme s BYZIm pisali o mailovom spama,nie o spama do databaz. opis obrazka ti nepomoze,ak nejaky spam robot prebehuje fora,weby a hlada retazce,kde je zavinac a na tie potom odosiela spamove maily....
Nick z IP 210.123.39.*** | 16.5.2006 04:56
Great work!
[url=http://jztvxcak.com/ojkr/tklf.html]My homepage[/url] | [url=http://tlthllay.com/mgry/juzj.html]Cool site[/url]
Britney z IP 222.111.194.*** | 16.5.2006 04:57
Thank you!
<a href="http://jztvxcak.com/ojkr/tklf.html">My homepage</a> | <a href="http://cqwpxqvf.com/ldns/yqub.html">Please visit</a>


Nový komentář

Téma:
Jméno:
Notif. e-mail *:
Komentář:
  [b] [obr]
Odpovězte prosím číslicemi: Součet čísel jedna a deset