Náhrada tagov zanorenych rekurzivne rubrika: Programování: PHP
Caute,
neviem si moc rady s jednou vecou, s dovodu, ze nie som az tak dobry kamarat s regularnymi vyrazmi v kombinacii s rekurziou.
Mam dajme tomu:
{form prvyForm} {label nazov} {form druhyForm} {label nazov} {/form} ..... {/form}
a potreboval by som ziskat taketo nieco:
<?php if ($form->exists('prvyForm')) { $__form_prvyForm = $form->get('prvyForm'); ?> <?php echo $__form_prvyForm['nazov']->getLabel(); ?> <?php if ($form->exists('druhyForm')) { $__form_druhyForm = $form->get('druhyForm'); ?> <?php echo $__form_druhyForm['nazov']->getLabel(); ?> <?php } ?> ..... <?php } ?>
V spolupraci s manualom php som sa dopracoval k regularnemu vyrazu ktory mi to "poseka" podla zanoreni:
function form ($input) { $regular = '~\{form ([a-zA-Z_]+)\}((?:[^{]|\{(?!/?form(.*)\})|(?R))+)\{/form\}~s'; if (is_array($input)) { $input[2] = preg_replace('~\{label ([a-zA-Z0-9_]+)\}~', '<?php echo $__form_'.$input[1].'[\'\1\']->getLabel(); ?>', $input[2]); // toto je samozrejme chybne, lebo prepise vsetky labely uz pri prvom prechode a teda budu mat vsetky labely $__form_prvyForm $input = '<?php if ($form->exists(\''.$input[1].'\')) { $__form_'.$input[1].' = $form->get(\''.$input[1].'\'); ?>'.$input[2].'<?php } ?>'; } return preg_replace_callback($regular, [$this,'form'], $input); } $vysledok = form($vstup);
a teraz neviem docielit to, aby sa v kazdom callbacku nahradil iba ten label ktory patri do zanorenia, ktore sa aktualne nahradza.. tie labely, ktore su hlbsie zanorene, aby ostaly nedotknute pokial na ne nepride rad..
uz som prehladal kde co, zda sa, ze neviem polozit otazku spravne po anglicky (moja slabina - slaba anglictina), lebo ani ujo google ma nechape..
vedel by niekto poradit?
Nastrel noveho riesenia (zatial funguje bez problemov)
pomocou preg_replace_callback si vyberiem vsetky tagy bez ohladu na ich obsah.. kedze sa callback vola pekne postupne od zaciatku obsahu po jeho koniec, viem si lepsie riesit zanorenie..
zavolame compile(' .... text .... ');
private $kolbeky = [ '~{form ([a-zA-Z_]+)\}~' => '_form', '~{/form}~' => '_formEnd', '~\{label ([a-zA-Z_]+)\}~' => '_formLabel', '~\{description ([a-zA-Z_]+)\}~' => '_formDescription', '~\{input ([a-zA-Z_]+)\}~' => '_formInput' ]; function compile ($obsah) { $skompilovany_obsah = preg_replace_callback('~\{[\*\$/a-zA-Z0-9_ ]+\}~', [$this, 'callback'] , $obsah); } function callback($matches) { // tu hladame uz zhodu presne na dany tag + callback foreach($this->kolbeky as $k=>$v) { $matches[0] = preg_replace_callback($k, [$this, $v], $matches[0]); } return $matches[0]; } // a teraz podstata riesenia $formNameBuffer = []; function _form ($matches) { // otvarame zanorenie , vlozime na "koniec" bufferu jeho meno $this->formNameBuffer[] = $matches[1]; return 'PHP KOD zamienajuci otvaraci tag {form}'; } function _formLabel ($matches) { $aktualnyNazovFormu = end($this->formNameBuffer); return ' a tu uz vieme nazov - $aktualnyNazovFormu - formu v ktorom sme prave zanoreny, lebo je to posledny ktory sa do bufferu zapisal'; } function _formEnd ($matches) { $aktualnyNazovFormu = array_pop($this->formNameBuffer); return ' kedze sa nam tag {form} zatvara, odoberame jeho nazov z bufferu, dalsi najdeny tag label bude mat nazov predchadzajuceho formu, lebo ten sa zapisal pred nim'; }
(kod neberte doslovne, je to len koncept pisany z hlavy, avsak overeny ze funguje)
ma to napr. aj dalsie vyhody, ze ak neexistuje zaznam vo formNameBuffer, je chyba v tagoch, to iste ak po konci kompilacie nebude formNameBuffer prazdny je to chyba (nie je uzavrety tag, nie je otvoreny atd) - skompilovany obsah bude neplatny..
Komentáře
- Taco : No, když ti to funguje, tak ti to funguje, ale nemyslel jsem to takhle. Já bych to dělal rekurzí; oproti tvému řešení, kdy máš vlastně furt lineární seznam výrazů, a jen na ně uplatňuješ ty funkce. — 23.6.2018
- mario2402 : pri rekurzii mi ostaval ten problem, ze som nedokazal pri prvom prechode "vyclenit" tie dalsie zanorene tagy, resp. vedel.. ale uz by to bolo zlozitejsie ako toto riesenie, + tu je aj vyhoda, ze je lahko poznat ci su tagy spravne otvorene a uzavrete.. ale dakujem za radu, lebo si ma nakopol, aj ked inym smerom :) — 23.6.2018
Pro zobrazení všech 3 odpovědí se prosím přihlaste:
Nebo se přihlaste jménem a heslem:
Komentáře