Nové schopnosti regulárních výrazů

Školení, která pořádám

Od verze 4.3.3 je možné funkci preg_match předat parametr offset, při jehož použití se může hodit regulární výraz \G – ten strefí začátek podřetězce. Od stejné verze je také možné vypnout speciální význam všech znaků, pokud je uzavřeme mezi \Q a \E.

Ke greedy (.+) a ungreedy (.+? nebo přepínač U) kvantifikátorům se od PHP 4.3.3 přidávají possessive (.++). Ty snědí všechno co mohou, i kdyby to vedlo k nesplnění následující části regulárního výrazu, a dají se použít pro urychlení vyhodnocování. Místo [^"]+" je tedy rychlejší [^"]++", protože automat se nebude vracet ve snaze nalézt uvozovku (díky výrazu [^"] je jasné, že stejně žádnou nenajde).

Od PHP 4.3.3 je možné používat bohatší syntaxi u rekurzivních výrazů, protože je ale nepoužívám, k ničemu mi to není. Hodit by se snad mohlo (?1) mimo rekurzi, které se dovoluje odkázat na předchozí masku a umožňuje tak napsat třeba výraz ([-a-z0-9._]+)@(?1)\.[a-z]+. K dispozici jsou také pojmenované výrazy, které naplní výsledné pole kromě číselných také textovými klíči:

<?php
preg_match('~^(?P<username>[-a-z0-9._]+)@(?P<domain>[-a-z0-9._]+\\.[a-z0-9]+)$~i', $email, $matches);
print_r($matches); // array([0] => jakub@vrana.cz, [username] => jakub, [1] => jakub, [domain] => vrana.cz, [2] => vrana.cz)
?>

Osobně dávám u složitějších výrazů přednost tradiční syntaxi a zápisu list(, $username, $domain) = $matches.

Novinkou pro mě je, že od PHP 4.3.5 se UTF-8 znaky kontrolují. Hodit se může i schopnost strefit v UTF-8 režimu jediný bajt – to zařídí výraz \C.

Aktualizovaná knihovna také syntaxí (?C) podporuje tzv. callouts. Tento mechanismus umožňuje uprostřed vyhodnocování regulárního výrazu zavolat vlastní funkci, což se dá jednak použít pro ladění, a jednak je touto funkcí možné ovlivnit další vyhodnocování výrazu (úspěch, neúspěch, částečný neúspěch). V PHP ale nejde určit, jaká funkce se má volat při dosažení calloutu, takže se tento nový obrat použít nedá. V nepovolaných rukách by podle mě mohl napáchat víc škody než užitku.

Viz také: Další novinky v PHP 5.1.

Jakub Vrána, Seznámení s oblastí, 3.3.2006, diskuse: 8 (nové: 0)

Diskuse

@ss@ssIn:

Moc hezky, ale jak si sa dostal k tomuto: ?P<username>, lebo ja som toho nasiel o regex vela, ale toto tam nebolo :/

BTW: neda sa niekde stiahnut PHP manual aj s komentarmy od uzivatelov - bo ja ho mam len off a tie pripomienky vyzeraju byt huste :)

ikona spaze:

"It is possible to name the subpattern with (?P<name>pattern) since PHP 4.3.3. Array with matches will contain the match indexed by the string alongside the match indexed by a number, then."
-- http://www.php.net/manual/en/reference.pc….syntax.php

@ss@ssIn:

K certu som to mal pred nosom a som si top nevsimol, no co uz pod lampou byva najvecsia tma :)

ikona spaze:

ups, sem poslal nejak drive.. k tomu manualu s komentarema:
http://www.php.net/download-docs.php "Extended HTML Help"

@ss@ssIn:

Skvor som myslel cisto (d|x)html aby to slapalo aj pod linuxom a vo wine bez prav :/

medden:

Len by som chcel upozrniť, že pri pomenovaných subvýrazoch musí byť meno použité iba raz (teda unikátne).

Mimochodom, existuje nejaký spôsob, ako subvýrazy nejak hromadne pomenovávať? Teda niečo na spôsob
array([name0] => "meno1", [name1]=>"meno2")
alebo rovno
array([name] => array("meno1, "meno2"))
Takáto vecička by sa mi momentálne dosť hodila... Neviete o niečom?

RATMex B:

Aký je význam spomínaného possessive kvantifikátora? Jeho správanie je identické ako once-only subpattern a jeho jediný "účel" vidím v tom, že niečo, čo už v regulárnych výrazoch existovalo, bolo pridané ešte raz, ale v modrom.

ikona Jakub Vrána OpenID:

Opravdu to bude jen jiná syntaxe ke stejnému obratu.

Diskuse je zrušena z důvodu spamu.

avatar © 2005-2024 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.