使用 [^] 语法匹配一个词而不是它的反义词

Match a word but not its inverse using [^] syntax

我正在尝试制作一个正则表达式,匹配一个词,但匹配它的反义词。例如,如果我不想匹配的单词是 "no":

I am matching this word   // will pass
I am matching no word     // will not pass
I am matching on word     // will pass
I am matching that word   // will pass

我正在使用的当前正则表达式没有传递第三个示例,因为它没有匹配其中包含 "n" 或 "o" 的任何单词:

^I am matching ([^no]*) word$

实现此目的的最佳方法是什么 - 即匹配单词而不是字符集合?

对于上下文,我正在使用 Scala 和 Cucumber 编写验收测试,它们使用 Regex 将功能文件与其相应的 stepdef 进行匹配。我的真实示例更为复杂,因此我在此处对其进行了简化。另外,我知道我可以使用 Scala 中的 case/match 块捕获 (.*) 并处理该捕获组中的内容,但我很好奇如何使用 purely正则表达式。

您可以使用否定前瞻来测试您要匹配的文本:

^I am matching (?!no\b)(?<CapturedWord>\w+) word$

(?!no\b) - 这是一个negative lookahead. It tests the next two characters. If they are "no" followed by a word boundary,那么匹配失败。其他任何事情都会过去。前瞻实际上并没有捕获这些字符,所以...

(?<CapturedWord>\w+) - ...我们需要捕获字符以便继续测试的其余部分。我使用了 named group 因为它们通常更容易在以后的代码中引用。

另一个解决方案是描述所有不是 "on" 的词。请注意,如果你想否定一个长子字符串,这个解决方案并不方便,但是有几个没有前瞻功能的正则表达式引擎,这是唯一的方法:

^I am matching ([^\Wn]\w+|n[^\Wo]+|\w(?:\w{2,})?) word$

交替的第一个分支匹配所有不是 "no" 的 2 个字母的单词,最后一个分支匹配一个字母和 3 个或更多字母的单词。