匹配内重复匹配
Repeated match inside match
$regex = '/\[b\](.*?)\[\/b\]/is';
$string = '[b][b][b]string[/b][/b][/b]';
这只会匹配到第一个 [/b],所以如果我使用此正则表达式将此 bbcode 转换为 HTML,我将得到以下结果:
string[/b][/b]
我正在使用 PHP preg_replace,我怎么可以只用 string
,所以 3 html 个粗体标签。
您可以使用非捕获组来扩展重复计数:
(?:\[b\])+(.*?)(?:\[\/b\])+
^^^ ^^ ^^^ ^^
见demo
对于这种肮脏的情况:
this [b]is [b]a[/b][/b] test [b]string[/b]
递归解决方案有效:
\[b](?:(?:(?!\[b]).)*?|(?R))*\[/b]
PHP代码:
$str = 'this [b]is [b]a[/b][/b] test [b]string[/b]';
echo preg_replace_callback('~\[(\w+)](?:(?:(?!\[]).)*?|(?R))*\[/()]~', function($m) {
return "**".preg_replace("~\[/?$m[1]]~", '', $m[0])."**";
}, $str);
输出:
this **is a** test **string**
$regex = '/\[b\](.*?)\[\/b\]/is';
$string = '[b][b][b]string[/b][/b][/b]';
这只会匹配到第一个 [/b],所以如果我使用此正则表达式将此 bbcode 转换为 HTML,我将得到以下结果:
string[/b][/b]
我正在使用 PHP preg_replace,我怎么可以只用 string
,所以 3 html 个粗体标签。
您可以使用非捕获组来扩展重复计数:
(?:\[b\])+(.*?)(?:\[\/b\])+
^^^ ^^ ^^^ ^^
见demo
对于这种肮脏的情况:
this [b]is [b]a[/b][/b] test [b]string[/b]
递归解决方案有效:
\[b](?:(?:(?!\[b]).)*?|(?R))*\[/b]
PHP代码:
$str = 'this [b]is [b]a[/b][/b] test [b]string[/b]';
echo preg_replace_callback('~\[(\w+)](?:(?:(?!\[]).)*?|(?R))*\[/()]~', function($m) {
return "**".preg_replace("~\[/?$m[1]]~", '', $m[0])."**";
}, $str);
输出:
this **is a** test **string**