Java Scanner中的非捕获组将被忽略

Age*_*ntM 2 java regex delimiter java.util.scanner

我试图让扫描仪在每个@符号上分割一个字符串,但转义时除外(或在一行的开头)

我的RegEx: (?:[^\\])@

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

从我的理解来看,这应该符合我的意图。

但是,在扫描仪中使用此模式时,它只是忽略了以下事实:不应将非捕获组计入定界符,只是为了与之匹配,定界符(要删除/分割的部分)应仅为'@ '。因此,对于以下示例字符串:“ 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);
        }
    }   
}
Run Code Online (Sandbox Code Playgroud)

产量:

tes
here
Run Code Online (Sandbox Code Playgroud)

而不是预期的:

test
here
Run Code Online (Sandbox Code Playgroud)

ksh*_*ine 5

分隔符被认为是整个比赛,与组,捕获或不捕获无关。

您需要的是一个后向模式,此处的语法很容易,使用后向否定式。

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