在正则表达式中排除单词的方式(无需提前查找?)

时间:2019-11-07 04:53:58

标签: regex

如果我有输入:

hello cat
hellocat
hello gat

我想找到一个以“ hello”开头的行,后面没有“ cat”。

可以否定一个组,例如:

hello[^(\s?cat)]

还是您只能否定该位置的一组字符?如果没有,有什么方法可以做到这一点?我能够做到这一点的唯一方法就是积极向前:

hello(?!\s?cat)

但是我想知道是否还有其他方法可以做到这一点。

3 个答案:

答案 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

我想你会明白为什么他们发明了负面的超前行为...