1

我想测试一个正则表达式在 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}")应该返回 false,但返回 true。

在 Javascript 中,{3}正确地失败并出现Nothing to repeat异常。 在此处输入图像描述

4

2 回答 2

6

它似乎成功匹配空字符串:

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

该文档似乎没有将其定义为有效用途,但它通过了将检测到其他轻微语法问题并抛出的地方Pattern.error

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

于 2020-11-24T10:28:35.667 回答
1

{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, 正是n

这里X只是一个空字符串,所以这意味着一个空字符串恰好是 3 次,它仍然只是一个空字符串。

于 2020-11-24T10:30:34.807 回答