我需要匹配以下语句:
Hi there John
Hi there John Doe (jdo)
不匹配这些:
Hi there John Doe is here
Hi there John is here
所以我想这个regexp可以工作:
^Hi there (.*)(?! is here)$
但是它没有-我不确定为什么-我相信这可能是由捕获组(.*)引起的,所以我想也许让 * 操作符懒惰会解决这个问题...但是不行。这个regexp也不工作:
^Hi there (.*?)(?! is here)$
有人能给我指出解决方案的方向吗?
溶液
要检索结尾没有**is here
的句子**(如Hi there John Doe (the second)
),您应该使用(author @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条答案
按热度按时间uwopmtnx1#
.*
将找到匹配,而不管是否贪婪,因为在该行的末尾,没有随后的is here
(自然地)。解决这个问题的一个方法是使用lookbehind(从行尾检查,如果过去的几个字符与
is here
匹配)。^Hi there (.*)(?<! is here)$
正如Alan Moore所建议的,进一步将模式更改为
^Hi there (.*$)(?<! is here)
将提高模式的性能,因为捕获组将在尝试向后查找之前吞噬字符串的其余部分,从而节省了不必要的回溯。k3fezbri2#
从您的示例中还不完全清楚您是否希望防止“is here”在任何地方出现或仅在行尾出现。如果它不应该发生在任何地方,请尝试以下操作:
在每个字符之前,它检查下一个字符是否不是“is here”。
或者,如果你只想在它出现在一行的最后时排除它,你可以像Thorbear建议的那样使用负向后看:
您完全正确地解释了为什么您的表达式与所有输入行匹配。
.*
匹配了所有内容,并且(?! is here)$
的预测总是为真,因为“is here”永远不会在行尾之后出现(因为那里什么都没有)。toiithl63#
你不需要用正则表达式来解决你的问题,你只需要使用正则表达式来找出非预期的正则表达式是否匹配。当然,如果你已经知道这一点,只是想了解一下lookaheads/lookbehinds,你可以放弃这个答案的其余部分。
如果你使用你不希望输入字符串匹配的正则表达式:
这将给予你一个匹配
因此,您可以将逻辑放在应用程序级别,它应该在的地方(regex中的逻辑是一件糟糕的事情)。一点伪代码(我现在可以写出Java,但你已经明白了)