Ruby正则表达式 - 防止重叠匹配

时间:2013-10-06 15:43:10

标签: ruby regex

说我有一个标记<tag>,我希望在我的字符串中匹配<tag>...<tag>的组。我可以使用<tag>.*<tag>行的正则表达式。这匹配<tag>foo<tag>,这很好,但它也匹配<tag>foo<tag>bar<tag>,这是我不想要的行为。我希望匹配<tag>foo<tag>,然后排除bar,然后将结尾的标记作为下一个匹配的开头。我该怎么做?

2 个答案:

答案 0 :(得分:4)

最简单的解决方案是使用惰性quantifier,其中?强制.*匹配为少数字符(而不是很多,因为未经修饰的.*会尝试匹配):

<tag>.*?<tag>

更安全,更明确的解决方案是使用negative lookahead assertion

<tag>(?:(?!<tag>).)*<tag>

虽然在当前情况下,行为没有区别,但第二个可扩展以处理打开/关闭标记,确保嵌套标记不会错误匹配:

<tag>(?:(?!</?tag>).)*</tag>

应用于<tag>foo<tag>bar</tag>baz</tag>时将匹配<tag>bar</tag>,而不是<tag>foo<tag>bar</tag>作为具有延迟量词的解决方案。

答案 1 :(得分:2)

您使用.*的懒惰版本:

<tag>.*?<tag>
       ^

?使.*匹配为<tag>的第一场比赛。