Perl-compatible regulární výrazy v PHP (5) – modifikátory a líné kvantifikátory

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“.

Pokud použijeme modifikátor „extended“ (který má zkratku „x“), způsobí to dvě změny ve vyhodnocování regulárního výrazu:

  1. 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 \.
  2. Čá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.

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=“/(]*>)/ei“;

$replacement=“‚\\1‘.strtolower(‚\\2‘).’\\3′“;

$str=“

Nadpis



Text1



Text1

„;

$result=preg_replace($re,$replacement,$str);

Výsledkem (obsahem proměnné $result) pak je HTML kód:

Nadpis

Text1

Text1

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).

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é".

Tento článek byl původně publikován na serveru Interval.cz, kde naleznete
originální verzi článku.
Miroslav Pecka

Share
Published by
Miroslav Pecka
Tags: phpregexp

Recent Posts

GA4 (not set) problém & jeho řešení

Jak se zbavit (not set) v Session Source a Session Medium?

2 roky ago

Měření QR kódů a offline zdrojů do Google Analytics

Chcete doměřit efekt vaší offline reklamy, ze které vedete lidi na váš web? Jde to…

2 roky ago

5+1 věcí, které se online markeťák může naučit od ajťáka

Tenhle článek jsem měl rozepsaný fakt dlouho, ale je stále aktuální… Trápí mě, že opakovaně…

4 roky ago

Profesionál v onlinu: řemeslo + kontext + přesahy

Poslední dobou jsem se setkal s pár majiteli malých firem, kteří mají web a snaží…

4 roky ago

Nástroje pro tvorbu screencast videí

Občas se mě někdo ptá, co používám pro tvorbu screencastů a online videí. Které nástroje…

4 roky ago

7 Google Analytics video návodů pro efektivnější práci

V rámci 5 videí najdete 7 krátkých video tipů pro zefektivnění práce s Google Analytics…

5 roky ago