Perl-compatible regulární výrazy v PHP – modifikátory a líné kvantifikátory
V předchozím článku jsme nakousli téma modifikátorů, a protože modifikátory jsou příliš velkým soustem pro jeden článek, budeme v tomto tématu pokračovat a ukážeme si další čtyři modifikátory.
„Single line“
Jak jsem psal již v prvním článku, metaznaku .
(tečka) odpovídají všechny znaky kromě \n
. Pokud je však použit modifikátor „single line“ (který má ovšem v PHP interní označení „PCRE_DOTALL“), metaznak .
bude odpovídat i znaku konce řádku \n
. Modifikátor „single line“ má zkratku „s“.
„Extended“ aneb komentáře v regulárních výrazech
Pokud použijeme modifikátor „extended“ (který má zkratku „x“), způsobí to dvě změny ve vyhodnocování regulárního výrazu:
- Takzvané „bílé znaky“ v regulárním výrazu budou ignorovány, s výjimkou bílých znaků zapsaných v rámci skupiny znaků a s výjimkou případu, kdy bílému znaku bude předcházet zpětné lomítko
\
. - Část regulárního výrazu vpravo od znaku
#
až po znak konce řádku\n
(včetně) bude ignorována. To umožňuje vkládat ve složitých regulárních výrazech komentáře za znak#
.
Použití předvedu opět na ukázce:
$re=“/^ ah\n\toj$#můj vlastní komentář/x“;
$str=“ahoj“;
preg_match($re,$str); //vrátí int(1), tedy shodu
V uvedeném regulárním výrazu jsou obsaženy jak bílé znaky
(mezera), \n
, \t
, tak i text komentáře (#můj vlastní komentář
), který bude zcela ignorován.
„Evaluate“ – speciální modifikátor při nahrazování
Modifikátor se zkratkou „e“ (odvozeno od „evaluate“, anglicky „vyhodnotit“) může být použit pouze v regulárních výrazech, které jsou argumentem funkce preg_replace()
(respektive jinde je jeho použití ignorováno). Použijeme-li tento modifikátor, řetězec obsahující „text náhrady“ (v našich příkladech jsme pro něj používali proměnnou $replacement
) bude vyhodnocen jako PHP kód. Použití si ukážeme na příkladu, kdy bude naším cílem převést všechny HTML tagy na malá písmena (pozor, pouze tagy, nikoli atributy).
$re=“/(<\/?)([a-z]+)([^>]*>)/ei“;
$replacement=“‚\\1‘.strtolower(‚\\2‘).’\\3′“;
$str=“<H1>Nadpis</H1>
<P>Text1</P>
<P>Text1</P>“;
$result=preg_replace($re,$replacement,$str);
Výsledkem (obsahem proměnné $result
) pak je HTML kód:
<h1>Nadpis</h1>
<p>Text1</p>
<p>Text1</p>
Všimněte si, že kromě modifikátoru „e“ jsme použili i modifikátor „i“ (case insensitive). Jak vidíte, modifikátory lze tedy kombinovat. Stačí je zapsat za sebou za koncový oddělovač /
(na pořadí zápisu modifikátorů přitom nezáleží).
Regulárnímu výrazu v proměnné $re
odpovídají otevírací i uzavírací (případně nepárové) HTML tagy (s i bez atributů). Výraz je složen ze tří subvýrazů. Prvnímu subvýrazu odpovídá <
(otvírací tag) nebo </
(uzavírací tag). Druhému subvýrazu odpovídá sekvence znaků a-z (respektive A-Z, protože je použit modifikátor „i“), která představuje tag samotný. Třetímu subvýrazu odpovídá sekvence téměř libovolných znaků (vše kromě znaku >
) následovaná znakem >
.
Jak jste si asi všimli, tento příklad není nepodobný příkladu číslo 3 z předchozího článku. V tomto případě však zpracujeme řetězec představovaný zpětnou referencí na druhý subvýraz (\\2
) pomocí PHP funkce strtolower()
, která převádí řetězec na malá písmena. Protože je nyní (kvůli modifikátoru „e“) řetězec v proměnné $replacement
vyhodnocován jako PHP kód, musí být zpětné reference \\1
a \\3
uzavřeny (jakožto řetězce) do jednoduchých uvozovek a spojeny s dalšími řetězci (respektive řetězcem vracejícím volání funkce strtolower('\\2')
) pomocí běžného PHP operátoru pro spojování řetězců (.
– tečka).
Kvantifikátory podruhé – „lenost“ kontra „nenasytnost“
Již v prvním článku jsme si uvedli seznam všech kvantifikátorů a doposud jsme předpokládali, že se bude kvantifikátor snažit „pozřít“ co možná nejdelší řetězec. Tedy například, když porovnáme řetězec abbb
s regulárním výrazem ^a(b+)
, pak prvnímu subvýrazu bude odpovídat řetězec bbb
. Daný regulární výraz by se samozřejmě „spokojil“ (přesněji řečeno „by odpovídal“) i s řetězcem ab
, má-li však k dispozici delší řetězec, použije nejdelší možnou variantu, která ještě vede ke shodě. Proto říkáme, že kvantifikátory jsou standardně „nenasytné“ (greedy).
Pomocí „ungreedy“ modifikátoru (který má zkratku „U“ a v PHP interní označení „PCRE_UNGREEDY“) je možno přepnout chování kvantifikátorů z „nenasytného“ na „líné“ (lazy). Pokud se budou kvantifikátory chovat líně, bude se kvantifikátor snažit „pozřít“ minimální počet znaků, které jsou třeba, aby řetězec odpovídal regulárnímu výrazu. Pokud použijeme (v „ungreedy“ módu) opět řetězec abbb
a regulární výraz ^a(b+)
, prvnímu subvýrazu bude odpovídat jednoznakový řetězec b
. Zbytek řetězce bude ignorován (nepřehlédněte, že je použito pouze ukotvení za začátku pomocí ^
– vpravo od prvního výskytu b
až do konce řetězce tak může být cokoli).
Modifikátor „U“ zapne „líné“ chování kvantifikátorů globálně pro celý výraz. Je však také možné, aby „zlenivěly“ jen vybrané kvantifikátory v řetězci. Každý konkrétní kvantifikátor, který má „zlenivět“, musí být bezprostředně následován otazníkem (?
).
Místo kvantifikátorů ?
, *
, +
, {m,n}
, {m,}
(kde m je minimální počet výskytů a n je maximální počet výskytů – více viz první článek), můžeme použít jejich líné varianty ??
, *?
, +?
, {m,n}?
, {m,}?
.
Následující tabulka názorně ukazuje rozdíly v chování „nenasytných“ a „líných“ kvantifikátorů, respektive jaká část z modelového řetězce bbbbbb
bude odpovídat (vytvářet shodu) jednotlivým regulárním výrazům.
Regulární výraz | Shoda |
---|---|
b? | b |
b?? | (prázdný řetězec) |
b* | bbbbbb |
b*? | (prázdný řetězec) |
b+ | bbbbbb |
b+? | b |
b{2, 4} | bbbb |
b{2, 4}? | bb |
b{3,} | bbbbbb |
b{3,}? | bbb |
b{5} | bbbbb |
Doplňme ještě, že pokud je pomocí modifikátoru „U“ zapnuta globální „lenost“, přidáním otazníku za konkrétní kvantifikátor se jeho (lokální) chování přepne na „nenasytné“.
Starší komentáře ke článku
Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.
Mohlo by vás také zajímat
-
Jak zabezpečit váš chytrý telefon před kybernetickými hrozbami
30. listopadu 2023 -
Webový správce souborů Filestash – dojmy a recenze
29. července 2024
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024