1

在 Java 中,我无法让正则表达式按照我想要的方式运行,并编写了这个小 JUnit 测试来演示这个问题:

public void testLookahead() throws Exception {
    Pattern p = Pattern.compile("ABC(?!!)");
    assertTrue(p.matcher("ABC").find());
    assertTrue(p.matcher("ABCx").find());
    assertFalse(p.matcher("ABC!").find());
    assertFalse(p.matcher("ABC!x").find());
    assertFalse(p.matcher("blah/ABC!/blah").find());

    p = Pattern.compile("[A-Z]{3}(?!!)");
    assertTrue(p.matcher("ABC").find());
    assertTrue(p.matcher("ABCx").find());
    assertFalse(p.matcher("ABC!").find());
    assertFalse(p.matcher("ABC!x").find());
    assertFalse(p.matcher("blah/ABC!/blah").find());

    p = Pattern.compile("[A-Z]{3}(?!!)", Pattern.CASE_INSENSITIVE);
    assertTrue(p.matcher("ABC").find());
    assertTrue(p.matcher("ABCx").find());
    assertFalse(p.matcher("ABC!").find());
    assertFalse(p.matcher("ABC!x").find());
    assertFalse(p.matcher("blah/ABC!/blah").find()); //fails, why?

    p = Pattern.compile("[A-Za-z]{3}(?!!)");
    assertTrue(p.matcher("ABC").find());
    assertTrue(p.matcher("ABCx").find());
    assertFalse(p.matcher("ABC!").find());
    assertFalse(p.matcher("ABC!x").find());
    assertFalse(p.matcher("blah/ABC!/blah").find());  //fails, why?
}

除了标有注释的两行外,每一行都通过。除了模式字符串之外,这些分组是相同的。为什么添加不区分大小写会破坏匹配器?

4

2 回答 2

1

这两个不会抛出错误值,因为完整字符串中有与模式匹配的子字符串。具体来说,字符串blah与正则表达式匹配(三个字母后不带感叹号)。区分大小写的正确失败,因为blah不是大写。

于 2011-02-17T22:32:35.623 回答
1

您的测试失败,因为在这两种情况下,模式[A-Z]{3}(?!!)(with CASE_INSENSITIVE) 并[A-Za-z]{3}(?!!)找到至少一个匹配项"blah/ABC!/blah"(他们找到bla两次)。

一个简单的测试表明了这一点:

Pattern p = Pattern.compile("[A-Z]{3}(?!!)", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("blah/ABC!/blah");
while(m.find()) {
    System.out.println(m.group());
}

印刷:

bla
bla
于 2011-02-17T22:37:53.557 回答