为什么这个字符串匹配,即使它的一部分处于负先行状态

Why does this string match even though parts of it are in negative lookahead

为什么这个正则表达式

(?!(public|private|protected|abstract|final|static))(.*)\(\);

匹配这个字符串:

public Test();

尽管我说我想要一个空的 space,然后 no (public|...) 然后是一些东西然后 ();?我在这里做错了什么?

但是我想匹配这个:Test();

编辑:

为什么这不起作用(未找到匹配项),即使 regex101.com 匹配 Test();

final String test = "public class Test {\n" +
        "  Test();\n";

final Pattern ptrn = Pattern.compile("^  (?!(public|private|protected|abstract|final|static))(.*)\(\);");
final Matcher mtchr = ptrn.matcher(test);

while(mtchr.find())
    System.out.println("FOUND");

问题

您遇到的问题显示在下面的代码段中。正则表达式匹配,因为您的正则表达式未锚定到字符串中的某个位置。这意味着正则表达式将尝试匹配字符串中的每个位置。

正则表达式将首先尝试匹配 public Test(); 中的 p。由于否定前瞻包括 public,它将失败并尝试下一个位置:ublic Test(); 中的 u。由于 public 和其他词在此位置不存在,因此匹配成功!

var s = 'public Test();'
var r = /(?!(public|private|protected|abstract|final|static))(.*)\(\);/

console.log(s.match(r)[0])

修复

那么我们该如何解决这个问题呢?简单:锚定模式。添加 ^ 锚点会强制正则表达式从字符串的开头开始匹配。这意味着它只会尝试从字符串的开头(public Test();p 的位置)开始匹配,而不会尝试匹配字符串开头以外的任何地方(它不会尝试匹配匹配 u).

See regex in use here

^(?!(public|private|protected|abstract|final|static))(.*)\(\);

var a = [
  'public Test();',
  'Test();'
]
var r = /^(?!(public|private|protected|abstract|final|static))(.*)\(\);/

a.forEach(function(s) {
  console.log(r.test(s) ? s.match(r)[0] : '*** no match')
})