Regex
Miriam Tolke
- perl
0 Cheatah
Hallihallo,
ich habe ein kleines Verständnisproblem.
In PHP verlieren Sonderzeichen wie $ . + usw. ihre Sonderfunktion. Wie ist das aber in Perl - dazu habe ich leider nichts gefunden.
Ich verwende die folgenden Regex im preg_match-Aufruf von PHP.
"1.0" und /([0-9.]+)/ # matcht
"1x0" und /([0-9.]+)/ # matcht nicht
Das sieht also so aus, als würde der Punkt hier wirklich nur als Punkt gelten.
"1\0" und /([0-9\.]+)/ # matcht nicht
Ups?
"1\0" und /([0-9]+)/ # Fehler
Hier scheint der Backslash einfach weiter als Escape zu gelten und escapet die Klammer.
"1\0" und /([0-9\]+)/ # Fehler
Hier escapet er aber nicht sich selbst, sondern wieder die Klammer.
Also alles in allem recht inkonsistent.
Was ist jetzt also Sache und wie kann ich einen Backslash als Backslash schreiben?
Tschüß,
Miriam
Hi,
Das sieht also so aus, als würde der Punkt hier wirklich nur als Punkt gelten.
in einer Zeichenklasse ist dem so, ja.
"1\0" und /([0-9\.]+)/ # matcht nicht
"" ist das Escape-Zeichen, d.h. es nimmt dem folgenden "" seine Sonderbedeutung. Hier versuchst Du also (wenn man es auflöst), "1\0" auf "/([0-9.]+)/" zu matchen, was klappen sollte. Tut es das nicht, hast Du möglicherweise anderswo im Code einen Fehler.
"1\0" und /([0-9]+)/ # Fehler
Die Zeichenklasse enthält hier die Zeichen 0-9, ], +, ) und /, endet jedoch nicht.
Hier scheint der Backslash einfach weiter als Escape zu gelten und escapet die Klammer.
Korrekt.
"1\0" und /([0-9\]+)/ # Fehler
Nein, kein Fehler. Ich glaube, Du hast ein grundsätzliches Syntax-Problem.
Also alles in allem recht inkonsistent.
Eigentlich ist es bei Perl sehr einfach, im Gegensatz zu vielen anderen Sprachen, in denen man noch zusätzlich innerhalb der Quotes escapen muss etc.
Was ist jetzt also Sache und wie kann ich einen Backslash als Backslash schreiben?
"\"
Cheatah
Hi Cheatah,
danke für Deine Antwort!
Das sieht also so aus, als würde der Punkt hier wirklich nur als Punkt gelten.
in einer Zeichenklasse ist dem so, ja.
Gut, also geht das in PHP und Perl absolut gleich - das freut mich.
"1\0" und /([0-9\]+)/ # Fehler
Nein, kein Fehler. Ich glaube, Du hast ein grundsätzliches Syntax-Problem.
Ich habe unten mal meinen Code gepostet, ich kann da leider nix finden. Wenn Du mich auf meinen Fehler aufmerksam machen könntest, wäre das toll.
Also alles in allem recht inkonsistent.
Eigentlich ist es bei Perl sehr einfach, im Gegensatz zu vielen anderen Sprachen, in denen man noch zusätzlich innerhalb der Quotes escapen muss etc.
Naja, alle Zeichen verlieren ihre Sonderwirkung, nur der Backslash nicht, das finde ich halt inkonsistent.
Was ist jetzt also Sache und wie kann ich einen Backslash als Backslash schreiben?
"\"
Hmm, anscheinend nicht. Was ich jetzt durch rumprobieren rausgefunden habe ist, daß es mit "\" funktioniert, mit zweien aber nicht!
Hier mein ganzer Code - zum Ausprobieren:
<?php
$teststring = "1\0";
echo("<p>$teststring:".$teststring."</p>");
if(preg_match("/([0-9\]+)/", $teststring, $arr))
{
echo($arr[1]."<br>");
}
else
echo "Fehler";
?>
Ciao,
Miriam
Hoi Miriam,
Ich habe unten mal meinen Code gepostet, ich kann da leider nix finden. Wenn Du mich auf
meinen Fehler aufmerksam machen könntest, wäre das toll.
Das naechste mal sag doch bitte sofort, dass es sich um PHP, nicht um Perl handelt. Auch
wenn die Funktion preg_match heisst, sind einige Sachen doch zu beachten :)
Naja, alle Zeichen verlieren ihre Sonderwirkung, nur der Backslash nicht, das finde ich
halt inkonsistent.
Auch der verliert seine 'Sonderbedeutung'.
Was ist jetzt also Sache und wie kann ich einen Backslash als Backslash schreiben?
"\"
Hmm, anscheinend nicht. Was ich jetzt durch rumprobieren rausgefunden habe ist, daß es
mit "\" funktioniert, mit zweien aber nicht!
Das liegt daran, dass PHP seine RegExe als Funktionsparameter an die RegEx-Engine gibt.
Diese Funktions-Parameter sind normale Strings und werden dementsprechend ganz normal
interpoliert. Deshalb wird aus '\' nur '', und aus '\' wird '\'. Das ist ueberigens
eine Besonderheit von PHP: \\ muesste eigentlich zu \ werden.
if(preg_match("/([0-9\]+)/", $teststring, $arr))
preg_match("/([0-9\\]+)/",$teststring,$arr)
oder
preg_match('/([0-9\]+)/',$teststring,$arr);
Gruesse,
CK
Hi Christian,
Das naechste mal sag doch bitte sofort, dass es sich um PHP, nicht um Perl handelt. Auch
wenn die Funktion preg_match heisst, sind einige Sachen doch zu beachten :)
Mal abgesehen davon, daß ich eben um diese Besonderheit nicht wußte, hatte ich doch in meinem ersten Beitrag geschrieben "Ich verwende die folgenden Regex im preg_match-Aufruf von PHP."
Hmm, anscheinend nicht. Was ich jetzt durch rumprobieren rausgefunden habe ist,
daß es mit "\" funktioniert, mit zweien aber nicht!Das liegt daran, dass PHP seine RegExe als Funktionsparameter an die RegEx-Engine gibt.
Diese Funktions-Parameter sind normale Strings und werden dementsprechend ganz normal
interpoliert. Deshalb wird aus '\' nur '', und aus '\' wird '\'. Das ist ueberigens
eine Besonderheit von PHP: \\ muesste eigentlich zu \ werden.
Klick. Das isses also, verstanden.
Danke für diese Klarstellungen!
Ciao,
Miriam
Hoi Miriam,
Mal abgesehen davon, daß ich eben um diese Besonderheit nicht wußte, hatte ich doch in
meinem ersten Beitrag geschrieben "Ich verwende die folgenden Regex im preg_match-Aufruf
von PHP."
Oehm, ja, wo du es jetzt sagst... war etwas verwirrend.
Gruesse,
CK
Hi Cheatah,
danke für Deine Antwort!
Das sieht also so aus, als würde der Punkt hier wirklich nur als Punkt gelten.
in einer Zeichenklasse ist dem so, ja.
Gut, also geht das in PHP und Perl absolut gleich - das freut mich.
"1\0" und /([0-9\]+)/ # Fehler
Nein, kein Fehler. Ich glaube, Du hast ein grundsätzliches Syntax-Problem.
Ich habe unten mal meinen Code gepostet, ich kann da leider nix finden. Wenn Du mich auf meinen Fehler aufmerksam machen könntest, wäre das toll.
Also alles in allem recht inkonsistent.
Eigentlich ist es bei Perl sehr einfach, im Gegensatz zu vielen anderen Sprachen, in denen man noch zusätzlich innerhalb der Quotes escapen muss etc.
Naja, alle Zeichen verlieren ihre Sonderwirkung, nur der Backslash nicht, das finde ich halt inkonsistent.
Was ist jetzt also Sache und wie kann ich einen Backslash als Backslash schreiben?
"\"
Hmm, anscheinend nicht. Was ich jetzt durch rumprobieren rausgefunden habe ist, daß es mit "\" funktioniert, mit zweien aber nicht!
Hier mein ganzer Code - zum Ausprobieren:
<?php
$teststring = "1\0";
echo("<p>$teststring:".$teststring."</p>");if(preg_match("/([0-9\]+)/", $teststring, $arr))
{
echo($arr[1]."<br>");
}
else
echo "Fehler";
?>Ciao,
Miriam
Hallo Miriam,
Mag mich erinnern, dass ich dieses Problem auch schon hatte.
Folgendes habe ich nun ausprobiert...
"1\0" --> "/([0-9\]+)/"
deine Version, funktioniert anscheinend wirklich.
"1\0" --> "/([\\0-9]+)/"
sollte ja auch gehen...
jammert aber mit No ending delimiter '/' found in...
"1\9" --> "/([\\1-9]+)/"
vielleicht gehts ja so...
wenigstens keine Fehlermeldung.
Das ist doch das gleiche wie oben, nur dass ich den Zahlenbereich
anders gesetzt habe.
Er findet aber nicht den ganzen Ausdruck.
"1\0" --> "/([\0-9]+)/"
so sollte es ja nach PHP-Referenz funktionieren.
er findet aber nicht den ganzen Ausdruck.
"\" --> "/([\]+)/"
sollte eigentlich einen einzelnen Backslash finden.
aber er jammert mit missing terminating ] for character class...
er quotet sich also selber die ] weg.
"\" --> "/([\]+)/"
deine Version. funktioniert.
"\" --> "/([\\]+)/"
meine Version. funktioniert auch.
"1\0" --> "/([\\0-9]+)/"
"1\0" --> "/([0-9\\]+)/"
meine Version mit Zahlenbereich, die funktioniert nun korrekt.
gleich ob die Backslashes vor dem Zahlenbereich stehen oder dahinter.
FOLGERUNG...
Zu dem Fehler No ending delimiter '/' found in...
PHP ist mit C programmiert.
Eine Sequenz wie "\0" in einem String bezeichnet in C das Ende des Strings. Der PHP-Interpreter sieht hier also das Ende der Reg-Expression und quittiert dies mit einer Fehlermeldung weil der Reg-Expression nicht korrekt ist.
Wenn du
echo "ich bin \0 da";
schreibst
bekommst du
"ich bin "
Finde ich persönlich natürlich misserabel. Sollte abgefangen werden.
Also verwende nie die Sequenz "\0" in einem String.
Dann zu den Backslashes.
Ich denke der PHP-Interpreter macht aus 4 Backslashes 2 und das übergibt er erst der Reg-Expression-Maschine. Die Reg-Expression-Maschine sieht dann 2 Backslashes und macht aus diesen dann einen Backslash.
Warum das deine Spezialversion mit den 3 Backslashes am Schluss der Zeichenklasse funktioniert... keine Ahnung.
Mir wackelt jetzt dann der Kopf vor lauter \\\\....
Gruss, LenaLuna