HalloPHP

Phänomen Backslash im regulären Ausdruck

Nice to know | letzte Änderung am 29. Juni '10 um 17:52 Uhr

Der Backslash stellt in vielen Bereichen eine Sonderfunktion dar. So dient er zum Escapen von Single- oder Doublequotes innerhalb eines Strings und leitet Escape-Sequenzen ein. Innerhalb eines regulären Ausdrucks haben viele Zeichen eine besondere Bedeutung und müssen durch einen Backslash escaped werden, möchte man nach ihnen suchen.

Die Suche nach dem Backslash

Möchte man aber nach einem Backslash innerhalb eines regulären Ausdrucks suchen, reicht das alleinige Escapen des Backslashes nicht aus. Für die Suche nach einem einzigen Backslash werden alleine 4 von ihnen benötigt. Einer, nach dem gesucht wird, ein Zweiter, der ihn escaped, ein Dritter, um den Backslash, der zum Escapen eingesetzt wird, zu escapen und ein Vierter, um sicherzustellen, dass keine Escapesequenzen beim Einsatz von Doublequotes interpretiert werden.

preg_match('/\\\\/', $string);

Funktionstest mit nur 3 Backslashes

Bei diesem simplen Beispiel matched der Ausdruck sogar, wenn nur 3 Backslashes eingesetzt werden. Doch sollte man sich darauf nicht verlassen. Das PHP-Handbuch empfiehlt den Einsatz der 4 Zeichen nicht umsonst, denn bereits bei diesem Beispiel lässt uns der Ausdruck im Stich.

<?php
preg_match
("/\\\foo/"'\\foo'$match);

echo 
'<pre>'print_r($match), '</pre>';  

Weitere Tests ergeben, dass der Ausdruck weiterhin matched, wenn anstelle der Doublequotes auf Singlequotes zurückgegriffen wird. Fügt man allerdings z.B. noch ein g hinzu, matched der Ausdruck wieder unter Single- als auch unter Doublequotes.

preg_match("/\\\gfoo/", '\\gfoo', $match);

Deutung

Das liegt daran, dass \f in Doublequotes als eine Escapesequenz (siehe http://www.php.net/manual/de/regexp.reference.backslash.php) interpretiert wird. \g dagegen existiert als Escapesequenz nicht und der Ausdruck arbeitet daher "korrekt".

Antworten

nikosch | verfasst am 14. Juli '10 um 18:39 Uhr

#1

Dann will ich mal eine philosophische Frage anschließen: Im Manual sind \t, \n und \r etc. als Escapesequenzen angegeben. Diese Ausdrücke (siehe auch oben der Fehler mit \f) kann bzw. muss man im Ausdruck mit einem Backslash schreiben. Nun die Frage: Wenn \t, \r und \n denn auch in PHP-Strings bedeutungstragend sind, wer ist dann eigentlich verantwortlich dafür, dass diese Sequenzen im Ausdruck funktionieren? Man könnte ja denken, PHP setzt die als ganz normales Zeichen um (wie ja auch der Leerschlag im Ausdruck funktioniert) - wieso sind die Sequenzen dann aber in RegExpr spezifiziert? Wenn dagegen ErgEx die Sequenz verarbeitet, wieso muss das Backslash dann nicht escaped werden?

Ich weiß nicht, wie das in anderen Sprachen ist - Perl und JS z.B. benutzen ja keine Stringbegrenzer bei reg. Ausdrücken. Also: Nachlässigkeit der PHP-Macher? Bequemlichkeit?

Asipak | verfasst am 27. Juli '10 um 13:53 Uhr

#2

Sorry für die späte Antwort, aber ich weiß ehrlich gesagt nicht, was dich dabei jetzt genau beschäftigt. Ich habe deinen Kommentar jetzt mehrmals immer wieder gelesen, kann dir aber leider keine konkrete Antwort geben. Dazu kenne ich mich auch zu wenig mit regulären Ausdrücken und dem ganzen Drumherum, der Interpretation durch den Parser, aus.

Der Artikel ist (wiedermal) durch ein Thema unter php.de entstanden, wo der Hinweis aufkam, dass für eine Suche nach einem Backslash auch nur 3 Backslashes nötig seien. Ich wollte wissen warum und habe einige Tests an dem Ausdruck durchgeführt und untersucht. Die einizge Erklärung fand ich dann im Zusammenhang mit den Escapesequenzen.
Ich hoffe, dass meine Tests und Recherchen ausreichend waren und es nicht noch mit anderen Dingen zusammenhängt.

Ob das ganze mit Bequemlichkeit oder Nachlässigkeit zu tun hat, weiß ich nicht!