我有一个获取 BBcode 标签的正则表达式。除了一个小故障之外,它工作得很好。
这是当前的表达式:
\[([^=\[\]]+)[=\x22']*([^ \[\]]*)['\x22]*\](.+)\[/\1\]
以下是它成功匹配的一些文本及其构建的组:
[url=http://www.google.com]去 http://www.google.com%5DGo去谷歌![/url]
1:网址
2: http://www.google.com http://www.google.com
3:去谷歌!
[img]http://www.somesite.com/someimage.jpg[/img] http://www.somesite.com/someimage.jpg%5B/img%5D
1:图像
2:空
3: http://www.somesite.com/someimage.jpg 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\]
To this:
\[([^=\[\]]+)[=\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 表达式。