Java 扫描仪中的非捕获组被忽略

Non capturing group in Java Scanner is ignored

我试图让扫描器在每个 @ 符号上拆分一个字符串,除非转义(或在一行的开头)

我的正则表达式: (?:[^\])@

(?:            // Start of non-capturing group (0)
  [            // Match any characters in square brackets [
    ^\        // Match any non-\ character.
  ]            // ]
)              // End of non-capturing group (0)
@              // Match literal '@'

根据我的理解,这应该符合我的意图。

然而,当在扫描仪中使用此模式时,它只是忽略了一个事实,即非捕获组不应计入定界符,只是为了匹配定界符(removed/split at) 应该只是“@”。因此,对于以下示例字符串:"Hello@World",结果必须是 ["Hello"、"World"].

除了下面的代码示例 运行:

private static void test() {
    try (Scanner sc = new Scanner("test@here")) {
        sc.useDelimiter("(?:[^\\])@"); // Every unescaped @ sign.
        while (sc.hasNext()) {
            String token = sc.next();
            System.out.println(token);
        }
    }   
}

产量:

tes
here

而不是预期的:

test
here

定界符被视为整个匹配项,不考虑组、捕获或非捕获。

你需要的是后视模式,这里的语法更简单,负后视。

sc.useDelimiter("(?<!\\)@");

扫描器不使用捕获组

相反,你应该使用负向后视。所以你的模式看起来像这样:

(?<!\)@

这也清除了所需的否定 class。

其中 : 简单地替换为 <! 为了使非捕获组,负向组后面看。