Bbcode 解析器无法正常工作
Bbcode parser does not work correctly
我对 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]
结果:
实际上,在字符串 [color=#ff0000][color=#00ffff]text text text text text[/color] [/color]
中,您的正则表达式匹配第一个开始标签和第一个结束标签。避免这种情况的一种方法是稍微修改您的正则表达式,例如:
/\[color=(\#[0-9A-F]{6}|[a-z]+)\]([^[]*)\[\/color\]/
那么它只会匹配嵌套最多的标签。您需要在循环中执行此操作,而您的字符串包含 bbcodes。
你也可以通过 2 个替换来完成。一个用于开头,一个用于结束标记。
那些颜色标签的嵌套将不再重要。
$message = preg_replace('%\[color=(\#[0-9A-F]{6}|[a-z]+)\]%i', '<span style="color:">', $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:">',
'</span>'
], $message);
正如 Casimir et Hippolyte 所指出的,不考虑嵌套可能会产生不好的结果。
所以这是另一种使用 while 循环和递归正则表达式的方法:
$pattern = '%\[color=(\#[0-9A-F]{6}|[a-z]+)\].*?(((?R)|.)*?)\[\/color\]%i';
$replacement = '<span style="color:"></span>';
do {
$message = preg_replace($pattern, $replacement, $message, -1, $count);
} while ($count);
我对 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]
结果:
实际上,在字符串 [color=#ff0000][color=#00ffff]text text text text text[/color] [/color]
中,您的正则表达式匹配第一个开始标签和第一个结束标签。避免这种情况的一种方法是稍微修改您的正则表达式,例如:
/\[color=(\#[0-9A-F]{6}|[a-z]+)\]([^[]*)\[\/color\]/
那么它只会匹配嵌套最多的标签。您需要在循环中执行此操作,而您的字符串包含 bbcodes。
你也可以通过 2 个替换来完成。一个用于开头,一个用于结束标记。
那些颜色标签的嵌套将不再重要。
$message = preg_replace('%\[color=(\#[0-9A-F]{6}|[a-z]+)\]%i', '<span style="color:">', $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:">',
'</span>'
], $message);
正如 Casimir et Hippolyte 所指出的,不考虑嵌套可能会产生不好的结果。
所以这是另一种使用 while 循环和递归正则表达式的方法:
$pattern = '%\[color=(\#[0-9A-F]{6}|[a-z]+)\].*?(((?R)|.)*?)\[\/color\]%i';
$replacement = '<span style="color:"></span>';
do {
$message = preg_replace($pattern, $replacement, $message, -1, $count);
} while ($count);