Reputation: 579
$regex = '/\[b\](.*?)\[\/b\]/is';
$string = '[b][b][b]string[/b][/b][/b]';
This will only match until the first [/b], so if I use this regex to convert this bbcode to HTML I will end up with this:
string[/b][/b]
I'm using PHP preg_replace, how I can end up with just string
, so 3 html bold tags.
Upvotes: 1
Views: 95
Reputation: 48711
For such dirty cases:
this [b]is [b]a[/b][/b] test [b]string[/b]
A recursive solution works:
\[b](?:(?:(?!\[b]).)*?|(?R))*\[/b]
PHP code:
$str = 'this [b]is [b]a[/b][/b] test [b]string[/b]';
echo preg_replace_callback('~\[(\w+)](?:(?:(?!\[\1]).)*?|(?R))*\[/(\1)]~', function($m) {
return "**".preg_replace("~\[/?$m[1]]~", '', $m[0])."**";
}, $str);
Outputs:
this **is a** test **string**
Upvotes: 3
Reputation: 29431
You can use a non-capture group to extend the repetition count:
(?:\[b\])+(.*?)(?:\[\/b\])+
^^^ ^^ ^^^ ^^
See demo
Upvotes: 1