我的 BB 代码功能有问题。我已经测试了以下输入来替换:
Testtext! <b>text<u>testtext</u>test</b><b>test</b>
并得到这个(混合)输出:
Testtext! [b]text[u]testtext[/u]test</b>test<b>test[/b]
我的 PHP 代码:
function html_to_bbcode($input) {
$regex[] = '#\<b>((?:[^[]|\<(?!/?b>)|(?R))+)\</b>#im';
$regex[] = '#\<i>((?:[^[]|\<(?!/?i>)|(?R))+)\</i>#im';
$regex[] = '#\<u>((?:[^[]|\<(?!/?u>)|(?R))+)\</u>#im';
if (is_array($input)) {
$tag = explode('>', $input[0]);
$tag = str_replace('<', '', $tag[0]);
if ($tag == 'b') {
$input = '[b]'.$input[1].'[/b]';
} else if ($tag == 'i') {
$input = '[i]'.$input[1].'[/i]';
} else if ($tag == 'u') {
$input = '[u]'.$input[1].'[/u]';
}
}
return preg_replace_callback($regex, 'html_to_bbcode', $input);
}
(以及更多标签)
我找不到那个错误:(有人能解决这个问题吗?
首先,作为最佳实践,您可能不应该首先尝试使用正则表达式解析 HTML(但如果不能保证这是有效的 HTML,因为它来自不可信的来源,例如最终用户,那么……也许)。 有些 BBCode 库可能会有所帮助,但我个人没有任何使用它们的经验。
其次,当您从最外层的配对标签开始工作时,递归正则表达式模式可能是一个好主意。在这种情况下,在我看来,您打算从最内层的配对标签开始工作。
如果您要继续使用正则表达式,那么我可能会对以下循环
preg_replace()
脚本感兴趣。 演示
$text = <<<TEXT
Testtext! <b>text<u>testtext</u>test</b><b>test</b>
TEXT;
do {
$text = preg_replace(
'#<([biu])>((?:(?!</?(?1)>).)+)</\1>#i',
'[$1]$2[/$1]',
$text,
-1,
$count
);
} while ($count);
echo $text;
// Testtext! [b]text[u]testtext[/u]test[/b][b]test[/b]
这将替换最里面的标签对(不会被任何其他指定标签打断),直到完成所有可能的替换。