preg_replace vs. preg_match_all | Ersetzungsproblem
am 24.10.2006 19:18:52 von Andreas OttoServus zusammen,
mit folgendem Problem schlage ich mich gerade herum: Wir füttern ein
templatebasiertes CMS mit BBCode-artiger Formatierung. Da Linebreaks
per nl2br() umgesetzt werden, muss natürlich drauf geachtet werden,
dass diese Umsetzung so erfolgt, dass valider Code dabei herauskommt.
Lange Rede, kurzer Sinn: vor dem nl2br() sollen z.B. zwischen und
Folgendes RegEx-Pattern verwende ich:
'#(<(/th|/td|/tr|tr|table)[^>]*>)([^<]*)(?t)#Uis'
$cnt enthält den bereits in HTML umgeformten Content.
Beispiel a) funktioniert:
if(preg_match_all('#(<(/th|/td|/tr|tr|table)[^>]*>)([^<]+)(?t)#Uis',
$cnt, $r))
foreach(array_keys($r[0]) as $k)
$cnt =3D str_replace($r[0][$k], $r[1][$k].$r[4][$k], $cnt);
Beispiel b) funktioniert *nicht*:
$cnt =3D
preg_replace('#(<(/th|/td|/tr|tr|table)[^>]*>)([^<]*)(?t)#Uis',
'\\1\\4', $cnt);
Hat irgendjemand eine Idee, warum das so ist?
Hoch die Tassen,
Andreas
Re: preg_replace vs. preg_match_all | Ersetzungsproblem
am 24.10.2006 22:01:27 von Ulf KadnerAndreas Otto schrieb:
> Beispiel b) funktioniert *nicht*:
> $cnt =
> preg_replace('#(<(/th|/td|/tr|tr|table)[^>]*>)([^<]*)(?t)#Uis',
> '\\1\\4', $cnt);
>
> Hat irgendjemand eine Idee, warum das so ist?
Ja, in Singlequotes wird die Backreference nicht escapt.
MfG, Ulf
Re: preg_replace vs. preg_match_all | Ersetzungsproblem
am 25.10.2006 01:18:09 von Andreas OttoUlf Kadner schrieb:
> Ja, in Singlequotes wird die Backreference nicht escapt.
Doch, wird sie...
echo preg_replace('#^(\d+)(.*)$#', '\\2\\1', '12bla');
=> bla12
q.e.d. :)
Andreas
Re: preg_replace vs. preg_match_all | Ersetzungsproblem
am 25.10.2006 10:36:21 von Ulf KadnerAndreas Otto schrieb:
>> Ja, in Singlequotes wird die Backreference nicht escapt.
>
> Doch, wird sie...
>
> echo preg_replace('#^(\d+)(.*)$#', '\\2\\1', '12bla');
Schau doch bitte ins Manual bevor Du versuchst ein Gegenargument zu
finden! Es ist so wie ich schrieb.
MfG, Ulf
Re: preg_replace vs. preg_match_all | Ersetzungsproblem
am 25.10.2006 11:27:12 von Andreas OttoUlf Kadner schrieb:
> Andreas Otto schrieb:
> > echo preg_replace('#^(\d+)(.*)$#', '\\2\\1', '12bla');
>
> Schau doch bitte ins Manual bevor Du versuchst ein Gegenargument zu
> finden!
Ich *versuche* nicht ein Gegenargument zu finden, ich habe Dir nur
gezeigt, dass auch in single quotes escapte back references problemlos
aufgelöst werden.
Ob escaped oder nicht - die Problematik bleibt die gleiche: die
Ersetzungen werden nicht durchgeführt. Nein, es wird auch nicht
"irgend ein scheiß" zurückgegeben - die Ersetzungen finden einfach
nicht statt und $cnt bleibt so, wie es ist.
mfg'
Andreas
Re: preg_replace vs. preg_match_all | Ersetzungsproblem
am 25.10.2006 11:58:34 von Ulf KadnerAndreas Otto schrieb:
> Ulf Kadner schrieb:
>> Schau doch bitte ins Manual bevor Du versuchst ein Gegenargument zu
>> finden!
>
> Ich *versuche* nicht ein Gegenargument zu finden, ich habe Dir nur
> gezeigt, dass auch in single quotes escapte back references problemlos
> aufgelöst werden.
:-) Aber besser wirds damit halt nicht! Was ich Dir damit sagen wollte
ist nur das der Backslash unnötig ist.
> Ob escaped oder nicht - die Problematik bleibt die gleiche
Das kann gut sein.
> Ersetzungen werden nicht durchgeführt. Nein, es wird auch nicht
> "irgend ein scheiß" zurückgegeben - die Ersetzungen finden einfach
> nicht statt und $cnt bleibt so, wie es ist.
Gib doch mal ein vollständiges nicht funktionierendes Beispiel.
Ich kann das was Du schreibst leider nicht nachvollziehen!
$html = <<
muss wech
HTML;
$p = '#(<(/th|/td|/tr|tr|table)[^>]*>)([^<]*)(?t)#Uis';
$html = preg_replace($p,'\1\4',$html);
echo $html;
# Output ist wie erwartet:
MfG, Ulf
Re: preg_replace vs. preg_match_all | Ersetzungsproblem
am 25.10.2006 12:33:39 von Andreas OttoUlf Kadner schrieb:
> :-) Aber besser wirds damit halt nicht! Was ich Dir damit sagen wollte
> ist nur das der Backslash unnötig ist.
Dankend zur Kenntnis genommen :)
> Gib doch mal ein vollständiges nicht funktionierendes Beispiel.
>
> Ich kann das was Du schreibst leider nicht nachvollziehen!
Here we go:
$cnt =3D <<
foo | bar |
foo2 | bar2 |
HTML;
echo
"V1:\n",preg_replace('#(<(/th|/td|/tr|tr|table)[^>]*>)([^<]*)(?t)#Uis',
'\1\4', $cnt),"\n\n";
preg_match_all('#(<(/th|/td|/tr|tr|table)[^>]*>)([^<]+)(?t)#Uis',
$cnt, $r);
foreach(array_keys($r[0]) as $k)
$cnt =3D str_replace($r[0][$k], $r[1][$k].$r[4][$k], $cnt);
echo "V2:\n$cnt\n";
?>
Output:
V1:
foo | bar |
foo2 | bar2 |
V2:
foo | bar |
foo2 | bar2 |
--- CUT ---
Heute, mit frischen Energien und genügend Kaffee, ist mir das Problem
aufgefallen: die Pattern unterscheiden sich in einem Zeichen: ([^<]*)
vs. ([^<]+)
Ganz großes Gna, Asche auf mein Haupt und Narrenkappe drauf. :|
Re: preg_replace vs. preg_match_all | Ersetzungsproblem
am 25.10.2006 12:48:08 von Ulf KadnerAndreas Otto schrieb:
> Heute, mit frischen Energien und genügend Kaffee, ist mir das Problem
> aufgefallen: die Pattern unterscheiden sich in einem Zeichen: ([^<]*)
> vs. ([^<]+)
> Ganz großes Gna, Asche auf mein Haupt und Narrenkappe drauf. :|
:-) War mir auch nicht aufgefallen. Was solls.
MfG, Ulf
Re: preg_replace vs. preg_match_all | Ersetzungsproblem
am 25.10.2006 12:50:43 von Andreas OttoNachtrag: das hat noch nicht alles ersetzt, hier jetzt aber eine
funktionierende Version:
$c = 1;
while($c)
$cnt =
preg_replace('#(<(/th|/td|/?tr|table)[^>]*>)([^<]+)(?t)#is', '\1\4',
$cnt, -1, $c);
?>