帮助修复BBcode正则表达式

我有一个抓住bbcode标签的正则表达式。 除了小故障外,它的效果很好。

这是当前的表达式:

\[([^=\[\]]+)[=\x22']*([^ \[\]]*)['\x22]*\](.+)\[/\1\] 

以下是它成功匹配的一些文本及其构建的组:

[url = http://www.google.com]转到谷歌![/ url]
1:url
2: http : //www.google.com
3:去谷歌!

[IMG] http://sofzh.miximages.com/c%23/f [/ IMG]
1:img
2:NULL
3: http : //www.somesite.com/someimage.jpg

[quote] [quote]第一次嵌套引用[/ quote] [quote]第二次嵌套引用[/ quote] [/ quote]
1:引用
2:NULL
3:[quote]第一次嵌套引用[/ quote] [quote]第二次嵌套引用[/ quote]

所有这一切都很棒。 我可以通过对同一个正则表达式运行第三个匹配组来处理嵌套标记,并递归处理嵌套的所有标记。 问题在于使用[quote]标签的示例。 请注意,第三个匹配组是一组两个引用标记,因此我们期望两个匹配。 但是,我们得到一个匹配,如下所示:

[quote]第一次嵌套引用[/ quote] [quote]第二次嵌套引用[/ quote]
1:引用
2:NULL
3:第一次嵌套引用[/ quote] [quote]第二次嵌套引用

哈啊! 这根本不是我们想要的。 有一种相当简单的方法来修复它,我修改了这个正则表达式:

 \[([^=\[\]]+)[=\x22']*([^ \[\]]*)['\x22]*\](.+)\[/\1\] 

对此:

 \[([^=\[\]]+)[=\x22']*([^ \[\]]*)['\x22]*\](((?!\[/\1\]).)+)\[/\1\] 

通过添加((?!\[/\1\]).)如果第3个匹配组包含结束的BBcode标记,我们将使整个匹配无效。 所以现在这个工作,我们得到两个匹配:

[quote]第一次嵌套引用[/ quote] [quote]第二次嵌套引用[/ quote]

[quote]第一个嵌套引用[/ quote]
1:引用
2:NULL
3:第一次嵌套报价

[quote]第二次嵌套报价[/ quote]
1:引用
2:NULL 3:第二个嵌套引用

我很高兴修复它,但现在我们有另一个问题。 这个新的正则表达式在第一个上面失败,我们将两个引用标记嵌套在一个较大的引用标记下。 我们得到两个匹配而不是一个:

[quote] [quote]第一次嵌套引用[/ quote] [quote]第二次嵌套引用[/ quote] [/ quote]

[quote] [quote]抢先引用[/ quote]
1:引用
2:NULL
3:[quote]首先嵌套引用

[quote]第二次嵌套报价[/ quote]
1:引用
2:NULL
3:第二次嵌套报价

第一场比赛都是错误的,第二场比赛虽然结构合理,但不是理想的比赛。 我们希望与第三个匹配组的一个大匹配是两个嵌套的引用标记,就像我们使用第一个表达式时一样。

有什么建议? 我觉得我太近了。 如果我能跨越这个差距,我应该有一个相当强大的BBcode表达式。

任何帮助表示赞赏。

使用平衡组,您可以构建这样的正则表达式:

 (?> \[ (?[^][/=\s]+) \s* (?: = \s* (?[^][]*) \s*)? ] ) (? (?> \[(?[^][/=\s]+)[^][]*] | \[/(?<-innertag>\k)] | [^][]+ )* (?(innertag)(?!)) ) \[/\k] 

根据Kobi的例子简化。


在下面的:

 [foo=bar]baz[/foo] [b]foo[/b] [i][i][foo=bar]baz[/foo]foo[/i][/i] [i][i][i][i]foo[/i][/i][/i][i][i]foo[/i][/i][/i] [quote][quote][b][img]foo[/img][b]bold[/b][b][b]deep[/b][/b][/b][/quote]bar[quote]baz[/quote][/quote] 

它找到这些匹配:

  • [foo=bar]baz[/foo]
  • [b]foo[/b]
  • [i][i][foo=bar]baz[/foo]foo[/i][/i]
  • [i][i][i][i]foo[/i][/i][/i][i][i]foo[/i][/i][/i]
  • [quote][quote][b][img]foo[/img][b]bold[/b][b][b]deep[/b][/b][/b][/quote]bar[quote]baz[/quote][/quote]

http://ideone.com/uULOs上的完整示例

(旧版本http://ideone.com/AXzxW )