为什么没有为我的无效模式抛出 PatternSyntaxException?

Why is no PatternSyntaxException thrown for my invalid pattern?

我想测试正则表达式在 Java 1.8 中是否有效。0_241

public static boolean isRegExpValid(String regExp) {
    try {
        Pattern.compile(regExp);
        return true;
    } catch (PatternSyntaxException e) {
        return false;
    }
}

这里我正在测试一个正确的三位数正则表达式和一个不正确的正则表达式。

@Test
public void testValidRegexp() {
    assertTrue(isRegExpValid("\d{3}"));
}

@Test
public void testInvalidRegexp() {
    assertFalse(isRegExpValid("{3}"));
}

为什么我的第二个测试 testInvalidRegexp 失败了? isRegExpValid("{3}") 应该 return 为假,但 return 为真。

在 Java 脚本中,{3} 正确地失败并出现 Nothing to repeat 异常。

似乎成功匹配空串:

jshell> Pattern.matches("{3}x", "x")
 ==> true

The documentation 似乎没有将此定义为有效使用,但它通过了会检测到其他小语法问题的地方并抛出 Pattern.error.

要分析为什么实现接受这个,你需要弄清楚在解析模式时可以从哪里调用 Pattern#closure

{3} 是 Java 中的有效正则表达式,但 它只会匹配空字符串

这是代码演示:

jshell> Matcher m = Pattern.compile("{3}").matcher("A {3} here");
m ==> java.util.regex.Matcher[pattern={3} region=0,10 lastmatch=]

jshell> while (m.find()) { System.out.println( "<" + m.group() + "> | " + m.start() + " | " + m.end()); }

<> | 0 | 0
<> | 1 | 1
<> | 2 | 2
<> | 3 | 3
<> | 4 | 4
<> | 5 | 5
<> | 6 | 6
<> | 7 | 7
<> | 8 | 8
<> | 9 | 9
<> | 10 | 10

根据Pattern Javadoc,它定义了贪婪量词:

X{n} X, exactly n times

这里的X只是一个空字符串所以它的意思是一个空字符串刚好3次仍然是一个空字符串。