为什么空正则表达式和空捕获组正则表达式返回字符串长度加一个结果

您如何解释空正则表达式和空捕获组正则表达式返回字符串长度加一个结果?

public static void main(String... args) { { System.out.format("Pattern - empty string\n"); String input = "abc"; Pattern pattern = Pattern.compile(""); Matcher matcher = pattern.matcher(input); while (matcher.find()) { String s = matcher.group(); System.out.format("[%s]: %d / %d\n", s, matcher.start(), matcher.end()); } } { System.out.format("Pattern - empty capturing group\n"); String input = "abc"; Pattern pattern = Pattern.compile("()"); Matcher matcher = pattern.matcher(input); while (matcher.find()) { String s = matcher.group(); System.out.format("[%s]: %d / %d\n", s, matcher.start(), matcher.end()); } } } 

产量

 Pattern - empty string []: 0 / 0 []: 1 / 1 []: 2 / 2 []: 3 / 3 Pattern - empty capturing group []: 0 / 0 []: 1 / 1 []: 2 / 2 []: 3 / 3 

正则表达式引擎也考虑字符前后的位置。 你可以看到这样的事实:它们有^ (字符串的开头), $ (字符串的结尾)和\b字边界,它们在某些位置匹配而不匹配任何字符(因此在字符之间/之前/之后) 。 因此,我们在必须考虑的字符之间有N-1个位置,以及第一个和最后一个位置(因为^$将分别匹配),这会给你N + 1个候选位置。 所有这些都匹配完全不受限制的空模式。

所以这是你的比赛:

 " abc " ^ ^ ^ ^ 

对于N个字符,这显然是N + 1。

您将获得与允许零长度匹配的其他模式相同的行为,并且实际上不会在模式中找到更长的匹配。 例如,尝试\d* 。 它在输入字符串中找不到任何数字,但*很乐意返回零长度匹配。

正则表达式引擎被硬编码以在零长度匹配时前进一个位置(否则是无限循环)。 你的正则表达式与零长度子字符串匹配。 每个字符之间都有零长度的子串(想想“每个字符之间的间隙”); 此外,正则表达式引擎也会考虑字符串有效匹配位置的开始和结束。 因为长度为N的字符串在字母之间包含N+1间隙(计算正则表达式引擎所做的开始和结束),您将获得N+1匹配。