我正在尝试改进处理从字符串中清理BBCode的遗留PHP代码,并且目前面临列表问题。
列表的当前解决方案执行以下操作:
...
$search[] = sprintf('~[%s](.*)[/%s]~smUi', 'list', 'list');
$search[] = sprintf('~[%s=(.*)](.*)[/%s]~smUi', 'list', 'list');
$search[] = sprintf('~[%s]~i', '*');
$replace[] = '$1';
$replace[] = '$2';
$replace[] = '';
...
return preg_replace($search, $replace, $string);
当字符串类似于
[list]
[*]Item 1
[*]Item 2
[*]Item 3
[/list]
但是,如果它不在列表中,它也会剥离[*]
并且还会失败,例如:
[list]
[*][list]
[*]Item 1.1
[*]Item 1.2
[*]Item 1.3
[/list]
[*]Item 2
[*]Item 3
[/list]
是否可以仅使用 RegExp 来剥离[list]
或[list=1]
+[/list]
标签以及[*]
(如果它们在列表中)?
您可以使用
$search[] = sprintf('~[(%s)(?:=[^]]*)?]((?:(?![1b).)*?)[/1]s*~si', 'list');
$search[] = sprintf('~[%s]~i', '\*');
$replace[] = '$2';
$replace[] = '';
$count = 0;
do {
$string = preg_replace($search, $replace, $string, -1, $count);
}
while ($count > 0);
return $string;
请参阅 PHP 演示。
我合并了前两个正则表达式,因为它们基本上匹配相同(打开标签内的=.*?
部分只是可选的,我建议使用(?:=[^]]*)?
匹配=
然后匹配 0+ 字符,而不是]
1 或 0 次。
((?:(?![1b).)*?)
模式是一个经过调节的贪婪令牌,可确保匹配最内层的list
标签,1
此处匹配使用(%s)
捕获的标签名称。
$count
变量将保存用preg_replace
完成的替换次数,如果没有替换任何内容,则while
块退出。