der rechte Weg zu preg_replace.
Jens Irrgang
- php
Hallo,
ich arbeite mich in PHP ein. Und dabei bin ich auf ein kleines Problem gestossen, welches mir so ein bisschen den Nachmittag verleidet.
Ich habe einen Array $erstellen. In diesem befinden sich mehrere HTML-Fragmente, die ich zusammen bringen möchte. Geht auch ganz einfach mit dem Code-Schnipsel welches ich hier eingefügt habe.
$ausgabe = preg_replace("/###metas###\n/", $erstellen['metas'], $erstellen['haupt']);
$ausgabe = preg_replace("/###titel###\n/", $erstellen['titel'], $ausgabe);
$ausgabe = preg_replace("/###menu###\n/", $erstellen['menu'], $ausgabe);
$ausgabe = preg_replace("/###allelinks###\n/", $erstellen['allelinks'], $ausgabe);
$ausgabe = preg_replace("/###labels###\n/", $erstellen['labels'], $ausgabe);
Das sollte aber doch auch einfacher und vor allem flexibler gehen?
Mein bisheriger, nicht funktionierender, Lösungsansatz ist dieser:
$ausgabe = preg_replace("/###(.*)###\n/", $erstellen['\1'], $erstellen['haupt']);
Ob nun $erstellen['\1'] oder $erstellen[\1], PHP gibt mir immer diesen Fehler aus: Notice: "Undefined index: \1 in D:\home\www\web5\html\index.php on line 26"
Die Archiv-Suche hat mich nicht weiter gebracht.
PHP-Version 4.3.4
Danke im voraus
Jens
Moin!
$ausgabe = preg_replace("/###metas###\n/", $erstellen['metas'], $erstellen['haupt']);
$ausgabe = preg_replace("/###titel###\n/", $erstellen['titel'], $ausgabe);
$ausgabe = preg_replace("/###menu###\n/", $erstellen['menu'], $ausgabe);
$ausgabe = preg_replace("/###allelinks###\n/", $erstellen['allelinks'], $ausgabe);
$ausgabe = preg_replace("/###labels###\n/", $erstellen['labels'], $ausgabe);
Alle diese Operationen erfordern kein preg_replace, sondern nur ein str_replace - das geht dann auch noch mal wesentlich schneller von der Ausführungszeit her.
Das sollte aber doch auch einfacher und vor allem flexibler gehen?
Sicher. Man kann beispielsweise eine Schleife machen. Nur wirst du in keinem Fall drum herumkommen, für jedes Vorkommen des Strings eine Ersetzungsfunktion aufzurufen.
Mein bisheriger, nicht funktionierender, Lösungsansatz ist dieser:
$ausgabe = preg_replace("/###(.*)###\n/", $erstellen['\1'], $erstellen['haupt']);
Öhm, irgendwie klingt mir das auch ziemlich arg unmöglich. Die Referenz auf \1 ist Bestandteil des regulären Ausdrucks - sie als Arrayindex zu verwenden, wird vermutlich niemals gehen können.
Ob nun $erstellen['\1'] oder $erstellen[\1], PHP gibt mir immer diesen Fehler aus: Notice: "Undefined index: \1 in D:\home\www\web5\html\index.php on line 26"
Du hast zwei Möglichkeiten: Entweder durchsuchst du deinen String nach Vorkommen von ###STRINGTEXT###, wertest aus, was STRINGTEXT ist, und ersetzt die gesamte Zeichenmenge durch den Inhalt von $erstellen['STRINGTEXT'], oder du wertest aus, welche Keys in $erstellen enthalten sind, und führst eine Ersetzen-Operation auf ###KEYWERT### aus.
$ausgabe = "Testweise ###test### ersetzen, gerne auch zweimal: ###test###";
$erstellen['test']="diese Ausgabe";
foreach ($erstellen as $key=>$value)
{
$ausgabe = str_replace("###".$key."###",$value, $ausgabe);
}
echo $ausgabe;
- Sven Rautenberg
Hallo Sven,
Das sollte aber doch auch einfacher und vor
allem flexibler gehen?Sicher. Man kann beispielsweise eine Schleife
machen. Nur wirst du in keinem Fall drum
herumkommen, für jedes Vorkommen des Strings
eine Ersetzungsfunktion aufzurufen.
Er wird ;)
Mein bisheriger, nicht funktionierender,
Lösungsansatz ist dieser:$ausgabe = preg_replace("/###(.*)###\n/", $erstellen['\1'], $erstellen['haupt']);
Öhm, irgendwie klingt mir das auch ziemlich arg
unmöglich.
Ist es nicht.
Die Referenz auf \1 ist Bestandteil des
regulären Ausdrucks
korrekt.
sie als Arrayindex zu verwenden, wird vermutlich
niemals gehen können.
Es geht mit dem e-Modifier:
$text = preg_replace('/###([^#]+)###/e',"$var['\1']",$text);
Alternativ kann er auch die $[1-9]-Variablen
nutzen:
$text = preg_replace('/###([^#]+)###/',$var[$1],$text);
Gruesse,
CK
Danke euch beiden,
ich hatte sowas schonmal unter Perl benutzt, daher wunderte ich mich das es mit PHP nicht funktionieren sollte.
Dieses funktioniert prima bei mir.
Es geht mit dem e-Modifier:
$text = preg_replace('/###([^#]+)###/e',"$var['\1']",$text);
Dieses funktioniert bei mir nicht, wird mit folgender Fehlermeldung abgewiesen: Parse error: parse error, unexpected T_LNUMBER, expecting T_VARIABLE or '$' in D:\home\www\web5\html\index.php on line 30. Einzige Änderung durch mich ist $var in $erstellen. Auf der anderen Seite ist es aber auch egal, da ich ja jetzt zwei funktionierende Alternativen habe.
Alternativ kann er auch die $[1-9]-Variablen
nutzen:$text = preg_replace('/###([^#]+)###/',$var[$1],$text);
Dieses funktioniert auch sehr gut.
$ausgabe = "Testweise ###test### ersetzen, gerne auch zweimal:
###test###";
$erstellen['test']="diese Ausgabe";
»»
foreach ($erstellen as $key=>$value)
{
$ausgabe = str_replace("###".$key."###",$value, $ausgabe);
}
Welche der beiden Methoden ist den die "schnellste" im realen Betrieb?
Danke nochmals
Jens
Hallo Jens,
Dieses funktioniert bei mir nicht, wird mit
folgender Fehlermeldung abgewiesen: Parse error:
parse error, unexpected T_LNUMBER, expecting
T_VARIABLE or '$' in
Vielleicht stattdessen ${1} schreiben. Welche
Version von PHP nutzt du?
Welche der beiden Methoden ist den die
"schnellste" im realen Betrieb?
Das wirst du benchmarken muessen.
Gruesse,
CK
Hallo Christian,
mit ${1} funktioniert es genau so wenig. Aber wie schon erwähnt - es ist eigentlich egal, denn Deine andere Version funktioniert ja, und die Version von Sven Rautenberg ebenso. Ich habe jetzt die Qual der Wahl - wobei ich wohl Deine nehmen werden, da sie meiner Grundidee ja nicht so fern ist. Außerdem erhalte ich durch diese Version Fehlermeldungen wenn sie auf ###text### stößt ohne im Array $erstellen ein passendes Gegenstück zu finden. Und bei einer Seite mit umfangreichen Texten und Bildern geht ein ###text### eher mal unter als eine Fehlermeldung die das ganze Design (wenn man bei mir davon sprechen darf) durcheinander wirft.
Die benutzte Version ist 4.3.4
Danke,
Jens
Moin!
Ich habe jetzt die Qual der Wahl - wobei ich wohl Deine nehmen werden, da sie meiner Grundidee ja nicht so fern ist. Außerdem erhalte ich durch diese Version Fehlermeldungen wenn sie auf ###text### stößt ohne im Array $erstellen ein passendes Gegenstück zu finden.
Christians Version ersetzt alles, was in ###...### steht, durch den Inhalt von $erstellen[...], ohne darauf zu achten, ob dieser Schlüsselwert überhaupt existiert.
Ich hingegen ersetze alle Schlüsselwerte, die im Array vorkommen, und die im Ausgabestring als ###...### markiert sind.
Christians Version ersetzt (mit Fehlermeldung, sofern man die nicht abfängt/abschaltet) alle ###...###-Vorkommen, das Ergebnis enthält diese also garantiert nicht mehr (notfalls wird durch einen Leerstring ersetzt.
Meine Version beläßt Vorkommen von ###...### im Text, welche nicht im Array definiert sind. Damit sieht man sofort, welche Platzhalter nicht ersetzt werden und noch definiert werden müssen.
- Sven Rautenberg