如果我有输入:
hello cat
hellocat
hello gat
我想找到一个以“ hello”开头的行,后面没有“ cat”。
可以否定一个组,例如:
hello[^(\s?cat)]
还是您只能否定该位置的一组字符?如果没有,有什么方法可以做到这一点?我能够做到这一点的唯一方法就是积极向前:
hello(?!\s?cat)
但是我想知道是否还有其他方法可以做到这一点。
答案 0 :(得分:3)
还有一种不带环视的方式,我认为值得一提的是一个有趣的概念:/hello(?:\scat)|(hello\s.*)/
在这种情况下,我们首先匹配我们不想要的内容(但不捕获它),然后仅在第一部分失败的情况下捕获第二部分,这意味着在捕获中您将始终拥有不包含的内容cat
。
在此示例https://regex101.com/r/bydCGb/3中,您可以在“比赛信息”框中检查“第1组”捕获-并检查替换部分-我们从来没有cat部分。
根据您的情况,您可以说:如果存在捕获组1,请执行某些操作。
答案 1 :(得分:2)
您不能使用纯正则表达式轻松地做到这一点,而无需使用负前瞻。但是,如果您使用某种编程语言通过API进行这些正则表达式调用,则可以使用以下正号来表达匹配项:
^hello\b.*
以及以下否定项:
^hello cat\b
也就是说,有效匹配在第一个图案上为正,在第二个图案上为负。在Java中,建议的解决方案如下所示:
String input = "hello gat";
if (input.matches("hello\\b.*") && !input.matches("hello cat\\b.*")) {
System.out.println("MATCH");
}
else {
System.out.println("NO MATCH");
}
答案 2 :(得分:2)
我认为不使用否定的前瞻就不可能轻易做到。
您可以使用[^abc]
约定排除特定字符。但是,您必须明确排除cat,然后才允许几乎所有的cat。
例如
((hello)ca[^t]|(hello)c[^a]|(hello)[^c])
然后获取与hello
组相对应的捕获组。你好后的空格以及使该选项变得更难的地方。可以使用以下方法捕获此可选空间:
((hello)\sca[^t]|(hello)\sc[^a]|(hello)\s[^c]|(hello)ca[^t]|(hello)c[^a]|(hello)[^c ])
注意:它具有全部六个选项,最后一个选项增加了一个可选空间,以确保不会捕获前三个。
在这里测试:https://regex101.com/r/sgoHyJ/1
我想你会明白为什么他们发明了负面的超前行为...