如何修复 BBcode 正则表达式 [英] How to fix a BBcode regular expression

查看:64
本文介绍了如何修复 BBcode 正则表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a regular expression that grabs BBcode tags. It works great except for a minor glitch.

这是当前的表达式:

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

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

Here is some text it successfully matches against and the groups it builds:

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

[url=http://www.google.com]Go to google![/url]
1: url
2: http://www.google.com
3: Go to google!

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

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

[quote][quote]first nested quote[/quote][quote]second nested quote[/quote][/quote]
1: quote
2: NULL
3: [quote]first nested quote[/quote][quote]second nested quote[/quote]

这一切都很棒.我可以通过针对相同的正则表达式运行第三个匹配组来处理嵌套标签,并递归处理所有嵌套的标签.问题在于使用 [quote] 标签的示例.请注意,第三个匹配组是一组两个引号标记,因此我们期望有两个匹配项.然而,我们得到了一场比赛,就像这样:

All of this is great. I can handle nested tags by running the 3rd match group against the same regex and recursively handle all tags that are nested. The problem is with the example using the [quote] tags. Notice that the 3rd match group is a set of two quote tags, so we would expect two matches. However, we get one match, like this:

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

[quote]first nested quote[/quote][quote]second nested quote[/quote]
1: quote
2: NULL
3: first nested quote[/quote][quote]second nested quote

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

Ahhhh! That's not what we wanted at all. There is a fairly simple way to fix it, I modify the regex from this:

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

为此:

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

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

By adding ((?!\[/\1\]).) we invalidate the entire match if the 3rd match group contains the closing BBcode tag. So now this works, we get two matches:

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

[quote]first nested quote[/quote][quote]second nested quote[/quote]

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

[quote]first nested quote[/quote]
1: quote
2: NULL
3: first nested quote

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

[quote]second nested quote[/quote]
1: quote
2: NULL 3: second nested quote

我很高兴修复了它,但现在我们又遇到了另一个问题.这个新的正则表达式在第一个失败时我们将两个引号标签嵌套在一个更大的引号标签下.我们得到两个匹配而不是一个:

I was happy that fixed it, but now we have another problem. This new regex fails on the first one where we nest the two quote tags under one larger quote tag. We get two matches instead of one:

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

[quote][quote]first nested quote[/quote][quote]second nested quote[/quote][/quote]

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

[quote][quote]first nested quote[/quote]
1: quote
2: NULL
3: [quote]first nested quote

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

[quote]second nested quote[/quote]
1: quote
2: NULL
3: second nested quote

第一场比赛全错了,第二场比赛虽然格式正确,但不是理想的比赛.我们想要一个大匹配,第三个匹配组是两个嵌套的引号标记,就像我们使用第一个表达式一样.

The first match is all wrong and the second match, while well-formed, is not a desired match. We wanted one big match with the 3rd match group being the two nested quote tags, like when we used the first expression.

有什么建议吗?如果我能跨越这个差距,我应该有一个相当强大的 BBcode 表达式.

Any suggestions? If I can just cross this gap I should have a fairly powerful BBcode expression.

推荐答案

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

Using balancing groups you can construct a regex like this:

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

这篇关于如何修复 BBcode 正则表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆