否定前瞻混淆

negated lookahead confusion

我正在尝试匹配 符合模式 name (CA)barbaz (UK) 的字符串。我似乎已经使用答案 here 解决了问题,但这就是我的开始,我想知道为什么它不起作用:

var r1 = /^.+(?!\([A-Z]{2}\))$/;

r1.test('foo'); //true

r1.test('foo (US)'); //whoops -also true

从读取一个否定的前瞻 doc 我希望任何没有跟随的字符串,例如(JP) 将导致匹配,而任何 后跟例如(DE) 会失败。 (只满足前者)

我认为 .+ 可能是 "consuming" 的一切,取消了前瞻性,所以我尝试了

r2 = /^[^()]+(?!\([A-Z]+\))$/;

r2.test('name (US)'); //false

r2.test('foo('); //whoops -also false

但是我需要 foo( 之类的东西来匹配。

为什么我的第一次尝试失败了?

在您的第一个表达式中,.+ 消耗了整个字符串,然后测试了前瞻性 - 它不匹配,因为没有剩余字符。为实现您的目标,您可以使用 /^(?!.+\([A-Z]{2}\)$).+$/ - 首先检查不需要的结构是否存在,然后进行匹配。

查看 https://regex101.com/r/aG7xZ0/1 样本