REGEX:捕获组未跟随

时间:2012-08-01 14:21:52

标签: java regex negative-lookahead capturing-group

我需要匹配以下声明:

Hi there John
Hi there John Doe (jdo)

不匹配这些:

Hi there John Doe is here 
Hi there John is here

所以我认为这个正则表达式可行:

^Hi there (.*)(?! is here)$

但它没有 - 而且我不确定为什么 - 我相信这可能是由捕获组(。*)造成的,所以我认为可能让*运算符懒惰会解决问题......但是没有。这个正则表达式也不起作用:

^Hi there (.*?)(?! is here)$

有人能指出解决方向吗?

解决方案

要在最后检索句子不带 is here(例如Hi there John Doe (the second)),您应该使用(作者@Thorbear):

^Hi there (.*$)(?<! is here)

对于包含中间某些数据的句子(如Hi there John Doe (the second) is here John Doe(第二个)是所需数据),简单分组就足够了:

^Hi there (.*?) is here$

           ╔══════════════════════════════════════════╗
           ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║
           ║▒▒▒Everyone, thank you for your replies▒▒▒║
           ║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║
           ╚══════════════════════════════════════════╝

3 个答案:

答案 0 :(得分:4)

.*无论贪婪都会找到匹配,因为在该行的末尾,没有跟随is here(自然)。

对此的解决方案可能是使用lookbehind(从行尾看,如果过去几个字符与is here匹配)。

^Hi there (.*)(?<! is here)$

修改

正如Alan Moore所建议的那样,进一步将模式更改为^Hi there (.*$)(?<! is here)将提高模式的性能,因为捕获组将在尝试后视之前吞噬其余字符串,从而避免不必要的回溯

答案 1 :(得分:3)

如果你想阻止“在这里”发生在任何地方或者只是在一条线的末尾,你的例子并不完全清楚。如果不应该在任何地方发生,请尝试:

^Hi there ((?! is here).)*$

reFiddle example

在每个字符之前,它会检查下一个字符是否“在这里”。

或者,如果您只想在行的最末端将其排除,则可以使用负面的lookbehind,如Thorbear建议的那样:

^Hi there (.*)(?<! is here)$ 

你的表达式与所有输入行匹配,这是完全正确的。 .*匹配所有内容,前瞻(?! is here)$将永远为真,因为“在这里”将永远不会发生行结束后(因为没有任何内容)。< / p>

答案 2 :(得分:1)

你不需要用正则表达式来解决你的问题,你只需要使用正则表达式来找出非预期的正则表达式是否匹配。当然,如果您已经知道这一点,并且只是想了解前瞻/外观,那么您可以放弃其余的答案。

如果您使用正则表达式,希望您的输入字符串匹配:

badregex = (Hi there (.*)(is here))

这将为您提供匹配

Hi there, John is here

所以你可以把逻辑放在应用程序级别,应该是什么(正则表达式中的逻辑是一件坏事)。一点伪代码(我现在写出Java,但你明白了)

if (badregex.exactMatch(your_str))
   discardString();
   return;
if (goodregex.exactMatch(your_str))
   doStuff(your_str);