我遇到了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]
结果:
但如果一个接一个有两个颜色标签,它就无法正常工作:
[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]
结果:
答案 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。