<meta http-equiv='pics-label' content='(pics-1.1 "http://www.icra.org/ratingsv02.html" comment "ICRAonline EN v2.0" l gen true for "http://interval.cz" r (nz 1 vz 1 lz 1 oz 1 cz 1) "http://www.rsac.org/ratingsv01.html" l gen true for "http://interval.cz" r (n 0 s 0 v 0 l 0))' />
<h2>Perl-compatible regulßrnφ v²razy v PHP - specißlnφ typy uzßvorkovßnφ</h2>
<p id='prepend'>KulatΘ zßvorky jsme doposud pou₧φvali pro ohraniΦenφ subv²raz∙, a to bu∩ proto, ₧e jsme cht∞li subv²raz doplnit kvantifikßtorem, nebo proto, ₧e jsme se na °et∞zec odpovφdajφcφ subv²razu cht∞li odkazovat pomocφ zp∞tnΘ reference. KulatΘ zßvorky se ale v Perl-compatible regulßrnφch v²razech pou₧φvajφ takΘ k sestavenφ specißlnφch konstrukcφ, kterΘ ovliv≥ujφ chovßnφ regulßrnφho v²razu.</p>
<li>pojmenovanΘ subv²razy (named subpatterns), respektive pojmenovanΘ zp∞tnΘ reference</li>
<li>komentß°e (dalÜφ mo₧nost jejich zßpisu)</li>
<li>modifikßtory (dalÜφ mo₧nost jejich zßpisu)</li>
<li>"look ahead assetions" a "look behind assertions" (co₧ m∙₧eme v tomto kontextu p°elo₧it asi jako "tvrzenφ o nßsledujφcφm" a "tvrzenφ o p°edchßzejφcφm")</li>
<li>podmφn∞nΘ subv²razy</li>
</ul>
<h3>Uzßvorkovßnφ netvo°φcφ zp∞tnΘ reference</h3>
<p>Pokud pou₧ijeme nap°φklad regulßrnφ v²raz <samp>^a(bc)+d$</samp>, budeme moci vyu₧φt zp∞tnou referenci na prvnφ (jedin²) subv²raz. Jestli₧e vÜak vφme, ₧e zp∞tnou referenci nebudeme pot°ebovat, ale p°esto pot°ebujeme urΦit opakovßnφ urΦitΘ sekvence znak∙ (v naÜem p°φpad∞ <samp>bc</samp> nßsledovanΘ kvantifikßtorem <samp>+</samp>), pak m∙₧eme pou₧φt takzvanΘ <em>uzßvorkovßnφ netvo°φcφ zp∞tnΘ reference</em> (non-capturing parentheses).</p>
<p>Pokud pou₧ijeme regulßrnφ v²raz <samp>^a(?:bc)+d$</samp>, sekvence <samp>?:</samp> za levou kulatou zßvorkou zajistφ, ₧e na °et∞zec (<samp>bc</samp>) odpovφdajφcφ v²razu v t∞chto zßvorkßch se nebude mo₧no odkazovat pomocφ zp∞tnΘ reference. Pou₧itφ "uzßvorkovßnφ netvo°φcφho zp∞tnΘ reference" mß dv∞ v²hody. Jednak si poΦφtaΦ p°i zpracovßnφ regulßrnφho v²razu uÜet°φ prßci (respektive mφsto v pam∞ti), kdy₧ si nebude muset pamatovat zp∞tnΘ reference, jednak se tφmto zp∙sobem m∙₧e zp°ehlednit prßce se zp∞tn²mi referencemi v slo₧itΘm regulßrnφm v²razu.</p>
<h3>PojmenovanΘ subv²razy</h3>
<p>Ve slo₧it∞jÜφm regulßrnφm v²razu m∙₧eme mφt mnoho subv²raz∙, kterΘ tvo°φ zp∞tnou referenci. Pak nemusφ b²t snadnΘ se v oΦφslovßnφ jednotliv²ch subv²raz∙ vyznat. Krom toho se m∙₧e stßt, ₧e na zaΦßtku regulßrnφho doplnφte pozd∞ji dalÜφ subv²raz a vÜechny subv²razy (vpravo od n∞j) se tφm p°eΦφslujφ. VhodnΘ proto je jednotlivΘ subv²razy pojmenovat vlastnφm oznaΦenφm (m∙₧eme pou₧φt alfanumerickΘ znaky a podtr₧φtko).</p>
<p>TakzvanΘ <em>pojmenovanΘ subv²razy</em> (named subpatterns) m∙₧eme vyu₧φt p°i pou₧itφ funkce <code>preg_match()</code> ve tvaru <samp>preg_match($re,$str,$matched)</samp>, kde <samp>$matched</samp> je pole °et∞zc∙, kterΘ odpovφdajφ jednotliv²m subv²raz∙m. Toto pole je (jak jsme si °ekli ji₧ d°φve) standardn∞ indexovßno Φφsly jednotliv²ch subv²raz∙. Pokud vÜak n∞kterΘ subv²razy pojmenujeme, bude pole obsahovat i prvky s indexy odpovφdajφcφmi t∞mto pojmenovßnφm. Pro pojmenovßnφ subv²razu se pou₧φvß konstrukce <samp>(?P<jmeno>v²raz)</samp>.</p>
<p>Podφvejme se na modelov² p°φklad, v n∞m₧ mßme za ·kol otestovat, zda zadan² °et∞zec (datum) odpovφdß formßtu <samp>RRRR-MM-DD</samp> (p°iΦem₧ prvnφ dvojΦφslφ roku smφ b²t pouze <samp>19</samp> nebo <samp>20</samp>), a pokud odpovφdß, zobrazit jednotlivΘ Φßsti data (den, m∞sφc, rok).</p>
<p>Rozeberme si nejd°φve samotn² regulßrnφ v²raz. Tento v²raz je slo₧en ze t°φ subv²raz∙ (pro rok, m∞sφc a den) tvo°φcφch zp∞tnΘ reference, kterΘ jsou odd∞leny obyΦejn²m znakem pomlΦky. Prvnφ subv²raz <samp>(?P<rok>(?:19|20)[0-9]{2})</samp> je slo₧en z pojmenovßnφ subv²razu <samp>?P<rok></samp>, dßle z uzßvorkovßnφ netvo°φcφho zp∞tnou referenci <samp>(?:19|20)</samp> a nakonec ze skupiny znak∙ <samp>[0-9]</samp> nßsledovanΘ kvantifikßtorem <samp>{2}</samp> (poslednφ dvojΦφslφ roku). Druh² subv²raz <samp>(?P<mesic>[0-9]{2})</samp> se sklßdß op∞t z pojmenovßnφ subv²razu <samp>?P<mesic></samp>, za nφm₧ nßsleduje samotn² v²raz <samp>[0-9]{2}</samp> popisujφcφ dvojcifernΘ Φφslo. T°etφ subv²raz je s druh²m a₧ na pojmenovßnφ shodn².</p>
<p>V²Üe uveden² regulßrnφ v²raz nenφ zcela dokonal², zßm∞rn∞ jsem jej pro ·Φely demonstrace probφran²ch princip∙ zjednoduÜil. Regulßrnφmu v²razu <samp>[0-9]{2}</samp> toti₧ nap°φklad odpovφdß i sekvence znak∙ <samp>00</samp>. Krom toho regulßrnφ v²raz mß popisovat m∞sφc (respektive den v m∞sφci), tak₧e nap°φklad Φφslo <samp>56</samp> by takΘ nem∞lo b²t pova₧ovßno za sprßvn² vstup. DokonalejÜφm °eÜenφm jist∞ bude v²raz <samp>^(?P<rok>(?:19|20)[0-9]{2})-(?P<mesic>0[1-9]|1[0-2])-(?P<den>0[1-9]|[12][0-9]|3[01])$</samp>. Zde je pro popis m∞sφce pou₧ito <samp>0[1-9]|1[0-2]</samp> (mφsto p∙vodnφho <samp>[0-9]{2}</samp>) a pro popis dne v m∞sφci <samp>0[1-9]|[12][0-9]|3[01]</samp> (mφsto p∙vodnφho <samp>[0-9]{2}</samp>).</p>
<p>Vra¥me se nynφ jeÜt∞ na skok k poli <samp>$matched</samp>, kterΘ obsahuje °et∞zce odpovφdajφcφ jednotliv²m subv²raz∙m, a podφvejme se, co ve skuteΦnosti v naÜem p°φkladu obsahuje. K zobrazenφ obsahu pole jsme pou₧ili p°φkaz <samp>var_dump($matched)</samp>.</p>
<div class='sample'>
array(7) {
<br /> [0]=>
<br /> string(10) "2004-07-12"
<br /> ["rok"]=>
<br /> string(4) "2004"
<br /> [1]=>
<br /> string(4) "2004"
<br /> ["mesic"]=>
<br /> string(2) "07"
<br /> [2]=>
<br /> string(2) "07"
<br /> ["den"]=>
<br /> string(2) "12"
<br /> [3]=>
<br /> string(2) "12"
<br />}
</div>
<p>Jak vidφme, pole nemß Φty°i prvky, jak bychom mohli oΦekßvat, ale sedm prvk∙. Pokud toti₧ pou₧ijeme pojmenovanΘ subv²razy, hodnota odpovφdajφcφ subv²razu se do pole ulo₧φ dvakrßt. Jednou s indexem odpovφdajφcφm Φφslu subv²razu, podruhΘ s indexem (klφΦem) odpovφdajφcφm pojmenovßnφ subv²razu.</p>
<h3>Komentß°e</h3>
<p>Pokud mßme slo₧it∞jÜφ regulßrnφ v²raz, m∙₧eme do n∞j (i na n∞kolik mφst) vlo₧it vysv∞tlujφcφ komentß°e. Jedna mo₧nost, jak p°idat komentß°e, byla popsßna v p°edchozφm Φlßnku (pou₧itφ modifikßtoru "extended"). Druhou mo₧nostφ je vlo₧enφ specißlnφ konstrukce ve tvaru <samp>(?#<em>komentß°</em>)</samp> do regulßrnφho v²razu. Regulßrnφmu v²razu <samp>^a(?#m∙j komentß°)b$</samp> tak bude vyhovovat prßv∞ a pouze °et∞zec <samp>ab</samp>, proto₧e za komentß° se pova₧ujφ vÜechny znaky mezi <samp>(?#</samp> a <samp>)</samp>.</p>