如何修复BBcode正则表达式



我有一个捕获BBcode标记的正则表达式。它工作得很好,除了一个小故障。

当前表达式:

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

下面是一些它成功匹配的文本和它构建的组:

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

[img] http://www.somesite.com/someimage.jpg [/img]
1: img
2:空
3: http://www.somesite.com/someimage.jpg

[quote][quote]第一个嵌套引号[/quote][quote]第二个嵌套引号[/quote][/quote]
1:引用
2:空
3: [quote]第一个嵌套引号[/quote][quote]第二个嵌套引号[/quote]

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

[quote]第一个嵌套引号[/quote][quote]第二个嵌套引号[/quote]
1:引用
2:空
3:第一个嵌套引号[/quote][quote]第二个嵌套引号

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

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

:

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

通过添加((?![/1]).),如果第三个匹配组包含关闭BBcode标记,则整个匹配无效。现在它工作了,我们得到了两个匹配项:

[quote]第一个嵌套引号[/quote][quote]第二个嵌套引号[/quote]

[quote]第一个嵌套引号[/quote]
1:引用
2:空
3:第一个嵌套引号

[quote]第二个嵌套引号[/quote]
1:引用
2:空3:第二个嵌套引号

我很高兴解决了这个问题,但是现在我们有另一个问题。这个新的正则表达式在我们将两个引号标签嵌套在一个更大的引号标签下的第一个引号中失败了。我们得到两个匹配项而不是一个:

[quote][quote]第一个嵌套引号[/quote][quote]第二个嵌套引号[/quote][/quote]

[quote][quote]第一个嵌套引号[/quote]
1:引用
2:空
3: [quote]第一个嵌套引号

[quote]第二个嵌套引号[/quote]
1:引用
2:空
3:第二个嵌套引号

第一个匹配完全错误,第二个匹配虽然格式良好,但不是理想的匹配。我们想要一个大匹配,第三个匹配组是两个嵌套的引号标签,就像我们使用第一个表达式时一样。

有什么建议吗?如果我能跨越这个鸿沟我就会得到一个相当强大的BBcode表达式

使用平衡组,你可以构造一个像这样的正则表达式:

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

根据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)

最新更新