Autor Zpráva
Tomik
Profil
Dobrý podvečer všem diskutujícím,
prosím o radu ohledně nahrazování podřetězce jiným pomocí fce preg_replace_callback.

Mám řetezec s podřetězci v takovémto formátu: "<%nazev(parametr)%>", pricemz nazev je pokazde jiný musí odpovídat reg.v. ([a-z]+[a-z0-9_-]*),
a parametr může být cokoli, kromě ")%>" (tj. cokoli do prvního výskytu těchto tří znaků), parametr může být i prázdný a v tom případě je povolený i zápis "<%nazev%>" (tento zápis je tedy ekvivalentní k <%nazev()%>).

Prosím tedy o radu, jak sestavit reg. výraz, aby obsáhl všechna tato pravidla a dal se použít ve fci preg_replace_callback.

Vymyslel jsem toto: $neco = preg_replace_callback('/<%([a-z]+[a-z0-9_-]*)(([^)]*))%>/', 'funkce', $neco);, ale toto řešení nefunguje vyskytne-li se někde v parametru závorka.

Díky za všechny rady a reakce...

Tomik
Tomik
Profil
Četl jsem sice celý seriál na INTERVALU, ale příliš moudrý z toho nejsem. Poradí někdo? Díky...
Pavel Strejček
Profil
Zdravím,

já bych na to šel asi takhle:

$neco = "aaaa <%nazev(pa(r)ametr)%> cccc";

function callback($match) {
print_r($match);
return 'bbbb';
}

echo preg_replace_callback('/<%([a-z]+[a-z0-9_\-]*)\((.*)\)%>/s', callback, $neco);
Pilda
Profil
Mohl by mi prosím někdo vysvětlit, co přesně dělá funkce preg_replace_callback? česky...
nightfish
Profil
http://cz.php.net/preg_replace_callback

preg_replace_callback — Perform a regular expression search and replace using a callback
Description
mixed preg_replace_callback ( mixed pattern, callback callback, mixed subject [, int limit [, int &count]] )

The behavior of this function is almost identical to preg_replace(), except for the fact that instead of replacement parameter, one should specify a callback that will be called and passed an array of matched elements in the subject string. The callback should return the replacement string. See preg_replace() for description of other parameters.


preg_replace_callback - Provede vyhledání regulárního výrazu a nahrazení pomocí callbacku (odkazu na funkci)

Popis
mixed preg_replace_callback ( mixed vzor, callback odkazNaFunkci, mixed kdeNahradit [, int kolikNahradit [, int &pocet]] )

Chování této funkce je skoro shodné s funkcí preg_replace(), nicméně místo parametru, který určuje, čím se má hledaný vzor nahradit, uvedete odkaz na funkci, která bude zavolána s jedním parametrem, a to polem nalezených prvků v prohledávaném řetězci. Odkazovaná funkce by také měla vrátit řetězec, který je výsledkem po nahrazení vzoru. Popis ostatních parametrů naleznete u funkce preg_replace().

You'll often need the callback function for a preg_replace_callback() in just one place. In this case you can use create_function() to declare an anonymous function as callback within the call to preg_replace_callback(). By doing it this way you have all information for the call in one place and do not clutter the function namespace with a callback functions name not used anywhere else.

Pravděpodobně budete potřebovat callback funkci pouze jednou. V tomto případě můžete použít funkci create_function(), která vám umožní při volání preg_replace_callback() jako callback použít anonymní funkci. Tímto máte všechny informace v jednom místě a nezaneřaďujete si jmenný prostor funkcí funkcemi sloužícími jako cíle callbacků, které nejsou volané nikde jinde v programu.
Joker
Profil
Tomik
Dotaz: Konec parametru je závorka, nebo jen ta sekvence znaků: ')%>'
Tj. třeba následující příklady by byly v pořádku?
<%nazev(para)metr)%> - parametr = para)metr
<%nazev(para%>metr)%> - parametr = para%>metr

Jinak na "trefení" a kontrolu správnosti regulárního výrazu se mi líbí nástroj "The Regex Coach"- zadáte regulární výraz, testovací řetězec a barevně se označí část řetězce vyhovující regulárnímu výrazu.
http://weitz.de/regex-coach/
Pavel Strejček
Profil
Pilda
Je opravdu nutné oživovat měsíc a půl staré téma nesouvisejícím "RTFM dotazem" místo založení nového tématu?
Pavel Strejček
Profil
Joker
Tomik uvedl:
parametr může být cokoli, kromě ")%>" (tj. cokoli do prvního výskytu těchto tří znaků)

Možné řešení viz výše v mé odpovědi.
Joker
Profil
Pavel Strejček
OK, jsem si nevšiml, jak je to téma staré :-)

No, tak alespoň ten Regex Coach se třeba někomu hodí :-)
Pilda
Profil
Pavel Strejček
Z jiných fór jsem zvyklej nezakládat zbytečně nové topiky, pokud na to už topic nějaký existuje. Ta otázka byla jako "jen tak mimochodem" a RTFM na to neplatí, protože jsem se na to samozřejmě pokusil přijít sám pomocí google, ale nenašel jsem odpověď.

IMHO u příspěvku typu, který jsem napsal je podle mě úplně jedno jestli je v topiku, který je starý den, nebo rok, protože když na ten topic někdo narazí a má nějaké nesrovnalosti, tak je chce vědět a je mu úplně jedno kdy to kdo založil. Také roztáhnutí témata do několika topiků neni to pravé ořechové.

Kdyby to byl topic tipu "kdy vyjde PHP 3?", tak bych to pochopil, ale topic, kde se řeší například nějaké funkce je IMHO stále aktuální, bez ohledu na datum.

Tak se nezlob, že jsem tě svojí lamovitostí tak rozčílil.

nightfish
děkuju
Pavel Strejček
Profil
Do rozčílení mám daleko. RTFM na to platí protože se to dá přečíst v manuálu a pokud zadám do Google preg_replace_callback tak hned na první stránce mám odkaz na tuto stránku http://www.regularnivyrazy.info/php-pcre-perl-compatible.html, kde je jasná definice v češtině. IMHO téma vlákna bylo jiné. Vadilo mi, že již na mrtvé vlákno potom zbytečně odpovídají a plýtvají energií lidé, kteří si nevšimnou data. Což se mi nedávno taky stalo jinde.
Tomik
Profil
Tak po několika týdenní odmlce se vracím k tomuto problému. Bohužel řešení od Pavla Strejčeka není plně funkční, protože pokud bude řetězec zpracováván touto fcí např. takovýto:

$neco = "aaaa <%nazev(pa(r)ametr1)%> cccc <%nazev(pa(r)ametr2)%> dddd";

tak bude funkce callback zavolána pouze jednou a to s parametrem "nazev(pa(r)ametr1)%> cccc <%nazev(pa(r)ametr2)", což já nechci. Zadání je tedy pořád stejné. Chci aby byla fce zavolána s parametrem "pa(r)ametr1" a podruhé s parametrem "pa(r)ametr2". Poradí někdo?

Joker
<%nazev(para)metr)%> - parametr = para)metr -> toto je platné
<%nazev(para%>metr)%> - parametr = para%>metr -> toto není platné

Děkuji všem za pomoc.
Pavel Strejček
Profil
Aha, ono jich tam může být víc. To jsem přehlédl. Tak tedy omezíme žravost. Tak:

'/<%([a-z]+[a-z0-9_\-]*)\((.*?)\)%>/s'

a nebo tak:

'/<%([a-z]+[a-z0-9_\-]*)\((.*)\)%>/Us'
Tomik
Profil
Díky. :-) Jak se zdá, funguje to.
Toto téma je uzamčeno. Odpověď nelze zaslat.