php stürzt bei preg_match ab?
-
Ich hab nun auch noch mein Apache auf 1.3.28 updated => und immer noch derselbe Fehler.
-
es gibt ne maximale laenge fuer eine reg expression. vermutlich ist deine zu lang.
probiers mal mit ereg, da gibts angeblich keine begrenzung.
-
Mich würd mal interessieren, was das eigentlich macht?! Blick da nicht so ganz durch....
-
CarstenJ schrieb:
Mich würd mal interessieren, was das eigentlich macht?! Blick da nicht so ganz durch....
Es handelt sich um eine experimentelle Version eines Syntaxcoloring-Moduls für das phpBB.
Ich werd es mal mit ereg probieren.
-
ereg hat eine etwas andere Syntax. Dieses Pattern: "\\cpp\\\[/cpp\]" fischt mir aus diesem Text:
[cpp]1[/cpp] [cpp]2[/cpp]
folgendes heraus:
1[/cpp] [cpp]2
In der Perl-Syntax konnte ich das verhindern, indem ich ein ? hinter den * gesetzt habe. Wie geht das in der ereg-Syntax?
-
Mist!
Google ergab, dass die ereg-Funktionen keine "umschaltbare Gierigkeit" haben.Hat jemand einen Vorschlag, wie sich mein Ziel trotzdem erreichen lässt?
-
Ich hab es hinbekommen.
Ich benutze einfach gar kein preg/ereg, sondern eine Schleife, die genau dasselbe erledigt. Nur geschwindigkeitsmäßig ist es vielleicht etwas langsamer.
-
#\\9e59c35455\\\[/9e59c35455\]#
das ding verstehe ich irgendwie nicht, folglich kann ich nicht helfen...
erklaer mal was du damit machen willst, dann kann man sicher n regexp schreiben, dass das kann
-
Shade Of Mine schrieb:
#\\9e59c35455\\\[/9e59c35455\]#
das ding verstehe ich irgendwie nicht, folglich kann ich nicht helfen...
erklaer mal was du damit machen willst, dann kann man sicher n regexp schreiben, dass das kann
Das war nur ein verkürztes Beispiel. Im Original (in der alten Version) sah die reg-exp so aus:
#\[$lan:$uid\]((.|\\n)*?)\[/$lan:$uid\]#
Wobei $lan sowas wie cpp und $uid irgendeine ID vom Forum ist.
Ich zerlege das Pattern mal:
#\[
Die eckigen Klammern müssen maskiert werden, damit sie nicht als Bereichsangabe aufgefasst werden. Da aber der Backslash in PHP-Strings selbst wieder maskiert werden muss, ergeben sich zwei Backslashs.uid
Nach der öffnenden eckigen Klammer folgt der Inhalt des Tags. Der sieht z.B. so aus: cpp:9e59c35455\]
Die schließende eckige Klammer, auch maskiert.Das hier: ((.|\\n|\\r| |\\t)?) war Unsinn, richtig ist:
((.|\\n)?)
Jetzt wird es lustig.
Ich will das, was zwischen dem öffnenden und dem schließenden Tag steht, herausholen. Deswegen kommen erstmal runde Klammern um das ganze.
Zwischen den beiden Tags dürfen völlig beliebige Zeichen stehen. Der Punkt steht in Perl-Syntax für ein beliebiges Zeichen außer dem Zeilenumbruch. Deswegen die ODER-Verknüpfung mit \\n.
Von diesen beliebigen Zeichen dürfen 0 bis unendlich vorhanden sein (das *).
Das Fragezeichen am Ende ist wichtig, um dem Ausdruck die Gier abzugewöhnen.
Sonst hört der nämlich nicht beim ersten schließenden Tag, sondern erst beim letzten auf.\[/uid\]#
Und hier dasselbe wie am Anfang, nur mit einen Slash / davor. Das schließende Tag also.p.s.:
Die Rauten sind die Delimiter.
-
ne, in einem reg exp muss man das zum glueck nicht machen... ist ja unleserlich...
um das ganze zu kuerzen, machen wir aus:
#\\uid\\\[/uid\]#
einfach
# kapier ich nicht, lass es deshalb weg/[uid](.*?)]/uid]/is
und schon ists leichter zu lesen
-
Echt?
Das ist kein Perl, sondern PHP. Da ist es dem Interpreter egal, ob der string einen regexp oder was anderes darstellt. D.h. Escape-Sequenzen werden ausgeführt. <-- Meine Meinung, ich lasse mich gern eines besseren belehren.Aber dein Code erzeugt immer noch denselben Absturz. Scheint wirklich eine Begrenzung von preg zu sein. und ereg ist unbrauchbar, gierig wie es ist.
-
escape sequenzen gelten nur, wenn sie auch eine ist.
dh
"\c" ist das selbe wie '\c'
aber
"\t" ist das selbe wie TABbtw: du kannst auch ' nehmen um den string zu begrenzen -> dann gibts nur noch \' als escape sequenz.
-
Shade Of Mine schrieb:
btw: du kannst auch ' nehmen um den string zu begrenzen -> dann gibts nur noch \' als escape sequenz.
und \\ oder?
-
Shade Of Mine schrieb:
escape sequenzen gelten nur, wenn sie auch eine ist.
dh
"\c" ist das selbe wie '\c'
aber
"\t" ist das selbe wie TABIch dachte immer, das führt zu undefiniertem Verhalten. Wie bei C/C++.
Aber gut, spare ich mir halt die Doppel-\.Shade Of Mine schrieb:
btw: du kannst auch ' nehmen um den string zu begrenzen -> dann gibts nur noch \' als escape sequenz.
Nein, kann ich nicht. Denn dann werden die Variablen nicht mehr expandiert.
Obwohl, ich könnte es so machen:'#[' . $lan . ':' $uid . ']((.|\n)*?)[/' . $lan . ':' . $uid . ']'
Naja, man kann da noch was zusammenfassen:
$tag = $lan . ':' . $uid . ']'; '#[' . $tag . '((.|\n)*?)[/' . $tag.
Ist aber trotzdem nicht wirklich elegant.
btw:
Deine Version:
/[uid](.*?)]/uid]/isklappt nicht. Und zwar weil du Schrägstriche (/) und keine Rauten (#) als Delimiter nimmst. Dann müsste der normale / vor $lan nämlich maskiert werden, sonst erkennt preg dort das Ende des Patterns.
Als Begrenzer eines regulären Ausdrucks ist jedes Zeichen zulässig, das nicht im Pattern selbst vorkommt. Wenn es doch vorkommt, muss es maskiert werden. Ich könnte also z.B. auch Ausrufezeichen benutzen.
-
cd9000 schrieb:
Deine Version:
/[uid](.*?)]/uid]/isklappt nicht. Und zwar weil du Schrägstriche (/) und keine Rauten (#) als Delimiter nimmst. Dann müsste der normale / vor $lan nämlich maskiert werden, sonst erkennt preg dort das Ende des Patterns.
Als Begrenzer eines regulären Ausdrucks ist jedes Zeichen zulässig, das nicht im Pattern selbst vorkommt. Wenn es doch vorkommt, muss es maskiert werden. Ich könnte also z.B. auch Ausrufezeichen benutzen.dass das / maskiert gehört weiss ich, habs nur vergessen...
aber das mit den # ist mir neu