帮助修复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/AXzxW )