MyBB.de Forum

Normale Version: Suchproblem mit preg_replace
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Hallo zusammen,

Ich hab ein verzwicktes Problem mit der Funktion preg_replace. Ich hab ein Such- und ein Ersetzarray geschrieben, anhand derer ich bestimmte "Forencodes" mit html-Code ersetzen möchte. Ich hab ein vereinfachtes Beispiel heraus geschrieben.
Nach längeren Herumprobieren, bin ich darauf gekommen, dass die Buchstaben r, l und u nicht an irgendeiner Stelle stehen dürfen, an der jetzt Linkr steht, da sonst der komplette String ohne Ersetzung ausgegeben wird. Wenn die Buchstaben innerhalb der ersten eckigen Klammern auftaucht, scheint dies nichts auszumachen.

Da ich den Benutzern nun aber nicht vorschreiben kann die Buchstaben im Linknamen nicht zu benutzen, such ich nach einer Lösung, wie ich das Problem umgehen oder entfernen könnte.

Hier noch ein Codebeispiel:
PHP-Code:
$string "Dies [url=http://www.istreinBeispiel.de]Linkr[/url]";
    
$search = array ("/\[url=([^\]]*)\]([^\[\/url\]]*)\[\/url\]/");
$replace = array ("<a href=\"http://\\1\">\\2</a>");
    
$ergebnis preg_replace($search,$replace,$string); 

Ausgabe ist (ohne die Leerzeichen nach '[':
Code:
Dies [ url=http://www.istreinBeispiel.de]Linkr\[ /url]

Ohne das r, also nur mit Link funktioniert es problemlos...
Hoffe ich hab nur irgendwas im Suchmuster übersehen, aber ich komm einfach nicht drauf.
Schau dir einfach mal die regulären Ausdrücke an mit denen das MyBB arbeitet. Vielleicht hilft dir das schon weiter. Den Code findest du in der Datei inc/class_parser.php ab Zeile 236. Ansonsten könnte diese Klasse interessant für dich sein, speziell dieser Abschnitt.
Oh Mann, ich bin sowas von dumm.

Erstens mal vielen vielen Dank für den Hinweis auf die class_parser. Genau die Zeilen hab ich nämlich nicht gefunden (wollte aus Verzweiflung auch schon am MyBB Code abspickeln).
Ich hab aber heute während meiner Vorlesugen das komplette Manual zu den regulären Ausdrücken auf php.net durch gearbeitet und bin dabei endlich auf vorden Fehler aufmerksam geworden. Im Nachhinein könnt ich mich selber Ohrfeigen, die Fehlerstelle hab ich die letzten Abende dauernd übersehen...

Nun aber zur Behebung:
Der Teil [^\[\/url\]]* ist von daher schon sowas von falsch, weil er jedes einzelne Zeichen, sprich [, /, u, r, l, mit dem Suchstring vergleicht. Deswegen durften auch die Buchstaben u, r und l nicht im Linknamen vorkommen.

So nebenbei hab ich auch festgestellt, dass das Beispiel einen Fehler enthält. ich hab es wegen der Übersichtlichkeit zusammen gekürzt, und dabei vergessen, das zweite http raus zu nehmen (das wird eigentlich durch str_replace() ersetzt, falls der User es beim posten vergessen hat).

Hier noch der richtige Code, diesmal auch mit der http-Ersetzung:

PHP-Code:
//Callback-Funktion zur Ersetzung des evtl doppeltem 'http://'
/*Die Callback-Funktion sollte der normalen preg_replace() vorgezogen werden,
da sie schneller arbeitet.*/

function p_url($code) {
        return 
"<a href=\"http://".str_replace('http://','',$code[1])."\">".$code[2]."</a>";
    }

//Beispielstring
$string "Dies [url=http://www.isteinBeispiel.de]Link[/url]";

//Suchmuster am Beispiel für die URL-Code Ersetzung
$search = array ("/\[url=([^\]]*)\](.+)(?=\[\/url\])\[\/url\]/");
      
$ergebnis preg_replace_callback($search,"p_url",$string); 

Es wäre auch einfacher gegangen, indem ich im zweiten Submuster nur [^\[ ]* eingegeben hätte. Das hatte ich ursprünglich auch vor, allerdings bekommt man dann ein Problem, wenn man den Linknamen formatiert (z.B. Fettschrift).