Assoziative Arrays in preg_replace
broott
- php
hallo,
ich habe das Problem assoziative Arrays mit preg_replace zu benutzen:
Daher z.B.:
$lang= array("house"=>"Haus", "garden"=>"Garten");
$text = "Das [lang=house] mit [lang=garden]";
$text = preg_replace('#\[lang=(.*)\]#Uis', $lang['\1'], $text);
echo $text;
Das Ergebnis ist "Das mit", d.h. alles was dem Muster entspricht verschwindet ansttat ersetzt zu werden. Ich habe schon mir alle erdenklichen Möglichkeiten ausprobiert von '$lang[\1]', "$lang[\1]" bis "$lang['\1'] etc.. Am ehesten richtig scheint "$lang[\1]" als Replace zu sein, da wenn ich z.B. statisch "$lang[garden]" es richtig ersetzt wird (aber halt natürlich mit dem Ergebnis "Das Garten mit Garten"). Kennt da jemand die Lösung? Habe bisher nicht im Web gefunden dazu. Vielleicht liegt es an meinem Pattern, aber da habe ich auch schon jede Menge Varianten ausprobiert!
Danke für eure Hilfe!
Hi,
$lang= array("house"=>"Haus", "garden"=>"Garten");
$text = "Das [lang=house] mit [lang=garden]";
$text = preg_replace('#[lang=(.*)]#Uis', $lang['\1'], $text);
echo $text;
>
> Das Ergebnis ist "Das mit", d.h. alles was dem Muster entspricht verschwindet ansttat ersetzt zu werden. Ich habe schon mir alle erdenklichen Möglichkeiten ausprobiert von '$lang[\1]', "$lang[\1]" bis "$lang['\1'] etc.. Am ehesten richtig scheint "$lang[\1]" als Replace zu sein, da wenn ich z.B. statisch "$lang[garden]" es richtig ersetzt wird (aber halt natürlich mit dem Ergebnis "Das Garten mit Garten").
Das funktioniert dann aus dem einfachen Grund, dass der String bereits ausgewertet wurde, \*bevor\* das Ersetzen stattfindet.
"$lang[garden]" lässt sich bereits "im Voraus" auswerten - $lang['garden'] wäre natürlich die "korrekteste" Schreibweise.
Aber die Back Reference dort einsetzen zu wollen, bringt nichts, kann nichts bringen - weil die zu dem Zeitpunkt, wo der String geparst wird, noch gar nicht existiert.
> Kennt da jemand die Lösung?
Beschäftige dich damit, wie man eine Callback-Funktion an der Stelle aufruft, die das zu ersetzende als Parameter nimmt, und den Ersatz zurückgibt.
MfG ChrisB
--
Light travels faster than sound - that's why most people appear bright until you hear them speak.
Danke dir ChrisB für die schnelle Antwort! Hat sehr gut funktioniert mit preg_replace_callback() (Hatte die Funktion wohl immer übersehen!) :)
mfg
broott
echo $begrüßung;
$text = preg_replace('#[lang=(.*)]#Uis', $lang['\1'], $text);
Ich habe schon mir alle erdenklichen Möglichkeiten ausprobiert von '$lang[\1]', "$lang[\1]" bis "$lang['\1'] etc..
$lang['\1']: Backreferences werden nur in Strings ausgewertet. Ein Ausdruck als Parameter wird erst ausgewertet und dann übergeben. Du willst aber einen Ausdruck übergeben, ohne dass er vorher ausgewertet wird. So etwas ist nicht vorgesehen. PHP versucht also einen Index \1 im Array $lang zu finden, es gibt aber nur house und garden. <gebetsmühle>Das würde dir mit einer Notice angezeigt werden, wenn du das error_reporting auf E_ALL stehen hättest.</gebetsmühle>
"$lang[\1]" und "$lang['\1']": Wird aufgrund der "" von PHP ausgewertet bevor es übergeben wird. Entspricht in der Wirkung wie $lang['\1'].
'$lang[\1]' ist ein String. preg_replace() müsste den evaluieren, was den Modifizierer e erfordert. Siehe Handbuch zu preg_replace().
eval() ist mit allergrößter Umsicht zu verwenden, dass nichts ausgeführt wird, was nicht vorgesehen ist. Das gilt auch hier. Wenn du also Benutzereingaben mit diesem Muster verarbeitest, überlege dir, wie man Code einschleusen kann und wie man das verhindert. Recherchen zu preg_replace und eval können dabei helfen.
Und wie ChrisB schon ausführte gibt es preg_replace_callback(), womit man sich das eval und den Ärger damit sparen kann.
echo "$verabschiedung $name";