I'm trying to make a BBCode parser but i'm having a real hard time with nested bbcodes. I have this code:
<pre><?php
$text = 'start[quote]sub-start[quote]middle 1[/quote][quote]middle 2[/quote]sub-end[/quote]end';
function format_split ($text){
$string = (string) $text;
$out = array('');
$key = 0;
$unique_long = 'b|i|u|s|sup|sub|left|right|center|justify|quote';
while (strpos ($text,'[')!==false){
$vtype = false;
if (preg_match('@\\[('.$unique_long.')\](.*?)\[/\1\]@',$text,$matches)){
$vtype = 3;
$value = null;
$cont = format_split ($matches[2]);
}
if ($vtype){
$text = explode ($matches[0],$text,2);
$out[$key] .= $text[0];
$out[] = array (
'tag' => $matches[1],
'vtype' => $vtype,
'value' => $value,
'cont' => $cont
);
$out[] = '';
$key += 2;
$text = $text[1];
}
else {
$text = explode ('[',$text,2);
$out[$key] .= $text[0].'[';
$text = $text[1];
}
}
$out[$key] .= $text;
return $out;
}
var_dump (format_split ($text));
?></pre>
as you may realize, the expected result would be something like this:
array(3) {
[0]=>
string(5) "start"
[1]=>
array(4) {
["tag"]=>
string(5) "quote"
["vtype"]=>
int(3)
["value"]=>
NULL
["cont"]=>
array(5) {
[0]=>
string(9) "sub-start"
[1]=>
array(4) {
["tag"]=>
string(1) "quote"
["vtype"]=>
int(3)
["value"]=>
NULL
["cont"]=>
array(1) {
[0]=>
string(8) "middle 1"
}
}
[2]=>
string(0) ""
[3]=>
array(4) {
["tag"]=>
string(1) "quote"
["vtype"]=>
int(3)
["value"]=>
NULL
["cont"]=>
array(1) {
[0]=>
string(8) "middle 2"
}
}
[4]=>
string(7) "sub-end"
}
}
[2]=>
string(3) "end"
}
but if you test, you'll see the first quote tag ends where should be the end of the second quote tag that's inside it:
array(5) {
[0]=>
string(5) "start"
[1]=>
array(4) {
["tag"]=>
string(5) "quote"
["vtype"]=>
int(3)
["value"]=>
NULL
["cont"]=>
array(1) {
[0]=>
string(24) "sub-start[quote]middle 1"
}
}
[2]=>
string(0) ""
[3]=>
array(4) {
["tag"]=>
string(5) "quote"
["vtype"]=>
int(3)
["value"]=>
NULL
["cont"]=>
array(1) {
[0]=>
string(8) "middle 2"
}
}
[4]=>
string(18) "sub-end[/quote]end"
}