Zur Navigation

Verschachtelte BBCode

1 Jürgen.bcx

Hallo Miteinander,
ich brüte gerade über einem pikanten Problem. Bei unserem Webangebot sollen künftig auch Quote-BBCode-Tags angeboten werden, diese sollen verschachtelbar sein.

Beispiel:


(Quote_a)
{
  text
  (Quote_b)
    mehr text
  (/Quote_b)
(/Quote_a)

Ich habe schon versucht dies normal über preg_replace und preg_replace_callback abzuwickeln, aber der innere Teil vom BBCode (also das innere Zitat im obigen Beispiel) wird nicht ersetzt.
Ich denke die Erklärung dafür ist, dass der Regex mit dem Modifier Ungreedy ausgestattet ist (sonst würde es sowieso nicht richtig gehen) und nach dem ersten Replace nach dem Replace fortgefahren wird und nicht wie man annehmen könnte wieder von vorn.

Wie könnte man das bewältigen?

*edit: Ich habe mir gerade überlegt, dass man es vllt folgendermaßen lösen könnte:


do
{
  $text = preg_replace($bbcode,$replace,$text);
}
while(preg_match($bbcode,$replace,$text)===1));

Was meint ihr? Das Problem ist, dass preg_match nicht mit einem Array umgehen kann.

24.03.2010 02:38 | geändert: 24.03.2010 03:08

2 Jörg

Ich hatte so etwas auch schonmal mit einer Schleife (und ohne Ungreedy Modifier) umgesetzt.

Wozu brauchst du ein Array?

24.03.2010 09:45

3 Jürgen.bcx

Hallo Jörg,

ein Array verwende ich eigentlich nur der Einfachheit wegen. Ich benutze dabei die Keys als Patterns und Values als Replace, z.b.


$bbcode = array(
"/\[quote\](.*)\[\/quote\]/is" => "$1"
);

danach nehme ich die Replacements vor mit


$text = preg_replace(array_keys($bbcode),array_values($bbcode),$text);

Ich habe es inzwischen so gelöst, dass so lange Replacements vorgenommen werden, wie Matches vorhanden sind:


do
{
  $text = preg_replace(array_keys($bbcode),array_values($bbcode),$text);
}
while(bbCodeLooper($text,array_keys($bbcode))===true);

wobei die Funktion bbCodeLooper folgendermaßen aussieht:


function bbCodeLooper($text,$arr){
  $i = 0;
  while($i < count($arr)){
    if(preg_match($arr[$i],$text)===1){
      return true;
    }
  }
  return false;
}

Arrays in Verbindung mit dem bbCodeLooper bieten sich für mich an, da ich für verschiedene Umfelder (z.B. RSS) ein anderes BBCode-Array benötige. Die bbCodeLooper kann ich dabei jetzt ganz einfach mit dem zu prüfenden String und dem jeweiligen Array (bzw. dessen Keys) füttern.

Die Lösung funktioniert tadellos, meine Frage ist jetzt aber, ob es noch knapper und eleganter geht.

24.03.2010 13:53 | geändert: 24.03.2010 13:58

5 Jürgen.bcx

Also das QuickerUBB kann ich nicht empfehlen, habe eben mal üer den Source geschaut und der ist grauenhaft. Es wird immer noch ereg(i) verwendet und der Code ist meiner Meinung nach sehr aufgebläht und teils unvorteilhaft programmiert.

Bei meiner Lösung habe ich aus der do{}while();-Schleife noch eine einfache while()-Schleife gemacht, da es ja auch BBCode-freien Text gibt. Trotzdem danke für den Link, er ist bestimmt für den ein oder anderen hilfreich.

29.03.2010 11:59

Beitrag schreiben (als Gast)





[BBCode-Hilfe]