嵌套标签的正则表达式(维基媒体内容)

时间:2009-07-22 22:48:13

标签: regex

有一段时间没有完成正则表达式,并且有点生疏。

我正在尝试解析维基百科条目中的类别。我需要的是一个模式中包含的单个字符串,以两个开放括号开头,两端用两个右括号结束。

此查询大部分时间都有效 -

(\[\[)(?<category>.*[^\]#])([\]])

但是当结束括号旁边有逗号(',')时会出现问题。

这有一个令人遗憾的结果,即在解析以下文本时 -

nlocation = [[Seattle, Washington]], [[United States|USA]]|

它为“类别”

提取以下内容
Seattle, Washington]], [[United States|USA

很明显,逗号正在抛弃它,它正在寻找下一组。捕获打开和关闭双括号之间的每个值的最佳方法是什么?

4 个答案:

答案 0 :(得分:3)

问题不在于逗号,问题是.*将匹配“]] [[”和其他任何内容一样。 * 贪婪 - 它会尽可能多地匹配。要解决此问题,您可以使用非贪婪版本(根据RichieHindle的建议),或者您可以将.*更改为[^\]]* - 贪婪地匹配之外的任何内容关闭括号。这也应该可以解决问题。

此外,这些不是“嵌套”标签 - 即[[tag [[inside]] tag]]。这可能不是你想要的,因为我不认为这意味着维基媒体标记中的任何内容。

答案 1 :(得分:2)

通过添加问号来使您的通配符不贪婪:

(\[\[)(?<category>.*?[^\]#])([\]])

                    ^
                    Here is the edit

这将使其与各个类别相匹配。

答案 2 :(得分:0)

我认为你让它变得比它需要的复杂得多。这样做你想要的吗?

\[\[(?<category>[^\[\]]+)\]\]

答案 3 :(得分:0)

逗号根本不相关。您可以通过简单的测试确认自己。

这里没有嵌套。无论如何都不允许嵌套Wikilink。

您需要确保内部模式与关闭wikilink的双括号不匹配。这样,只要你遇到双括号序列,就会停止在正则表达式匹配中累积更多字符。正则表达式中的问题是.*匹配所有内容。解决这个问题的简单方法是use a non-greedy modifier。这样,比赛就会尽快终止。但是,如果您不想这样做或者您的正则表达式库不支持它,那么您需要明确排除应终止该模式的序列。

一种天真的方法是简单地完全排除右括号:[^]]*。但这还不够好。在wikilink的文本中允许单个结束括号 。因此,您需要接受单个括号,同时排除双括号。这应该这样做:

\[\[       # 2 opening brackets
(?<category>
  (
    ]?     # optional bracket
    [^]]   # always a non-bracket
  )*
)
]]         # 2 closing brackets

这将接受一个右括号,但只有在它后面跟一个非括号才能打破结束序列。

相关问题