我需要匹配以下声明:
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▒▒▒║
║▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒║
╚══════════════════════════════════════════╝
答案 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);