Bbcode解析器无法正常工作

时间:2017-08-06 14:39:32

标签: php regex bbcode

我遇到了BBCodes问题 - 这个preg_replace无法按预期运行:

$message = preg_replace("/\[color=(\#[0-9A-F]{6}|[a-z]+)\](.*)\[\/color\]/Usi", "<span style=\"color:\\1\">\\2</span>", $message);

这是正常的:

[color=#ff0000]text text text text text[/color]
[color=#00ffff]texttexttext[/color]

结果:

Correct result

但如果一个接一个有两个颜色标签,它就无法正常工作:

[color=#ff0000][color=#00ffff]text text text text text[/color] [/color]

[color=#ff0000]text text text[color=#00ffff]text text text text text[/color] [/color]

结果:

Incorrect resul

2 个答案:

答案 0 :(得分:2)

你也可以通过2次替换来做到这一点。一个用于开放,一个用于结束标记。

那些颜色标签的嵌套无关紧要。

$message = preg_replace('%\[color=(\#[0-9A-F]{6}|[a-z]+)\]%i', '<span style="color:$1">', $message);

$message = preg_replace('%\[/color\]%i', '</span>', $message);

或在1声明中:

$message = preg_replace(
[   '%\[color=(\#[0-9A-F]{6}|[a-z]+)\]%i',
    '%\[/color\]%i'
],
[   '<span style="color:$1">',
    '</span>'
], $message);

正如Casimir et Hippolyte指出的那样,不考虑嵌套可能会产生不好的结果。

所以这是另一个使用while循环和递归正则表达式的方法:

$pattern = '%\[color=(\#[0-9A-F]{6}|[a-z]+)\].*?(((?R)|.)*?)\[\/color\]%i';   
$replacement = '<span style="color:$1">$2</span>';

do {
    $message = preg_replace($pattern, $replacement, $message, -1, $count);
} while ($count);

答案 1 :(得分:1)

实际上,在字符串allusers中,您的正则表达式将第一个打开与第一个结束标记匹配。避免这种情况的一种方法是稍微修改你的正则表达式,例如:

[color=#ff0000][color=#00ffff]text text text text text[/color] [/color]

然后它只匹配最嵌套的标签。您需要在循环中执行此操作,而您的字符串包含bbcodes。