3

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

这是当前的表达式:

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

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

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

[img] http://www.somesite.com/someimage.jpg[/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\]

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

[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 表达式。

4

1 回答 1

4

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

(?>
  \[ (?<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

于 2011-08-11T02:49:47.523 回答