非贪婪的正则表达式并不是最接近的选择

时间:2012-02-05 16:10:39

标签: regex

我的正则表达式不会选择与内部文本最接近的'cont'对。我该如何解决这个问题?

输入:

cont cont ItextI /cont /cont

正则表达式:

cont.*?I(.*?)I.*?/cont

匹配度:

cont cont ItextI /cont

匹配我需要:

cont ItextI /cont

2 个答案:

答案 0 :(得分:12)

cont(?:(?!/?cont).)*I(.*?)I(?:(?!/?cont).)*/cont

只会匹配最里面的块。

<强>解释

cont        # match "cont"
(?:         # Match...
 (?!/?cont) # (as long as we're not at the start of "cont" or "/cont")
 .          # any character.
)*          # Repeat any number of times.
I           # Match "I"
(.*?)       # Match as few characters as possible, capturing them.
I           # Match "I"
(?:         # Same as above
 (?!/?cont)
 .
)*
/cont       # Match "/cont"

这明确禁止cont/cont出现在开场cont和待捕获文本之间(以及该文字与结束/cont之间)。

答案 1 :(得分:2)

您在cont cont ItextI /cont上匹配的原因是正则表达式匹配第一个“cont”上的模式cont的第一部分,然后它使用不情愿的.*?来吞噬空格,下一个连续和ItextI之前的空格。当它达到ItextI时,它会将I识别为匹配模式的下一部分,并继续使用正则表达式的其余部分。正如minitech写的那样,这是因为正则表达式从字符串的开头起作用并找到最早可能的匹配。

如果你可以对空白做出假设,你可以写:

cont\s+I(.*?)I\s+/cont

这将在上面的示例中匹配。