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?
}

コメントでマークされた 2 行を除いて、すべての行が通過します。グループ化は、パターン文字列を除いて同一です。大文字と小文字を区別しない機能を追加するとマッチャーが壊れるのはなぜですか?

4

2 に答える 2

1

テストは失敗します。どちらの場合も、パターン[A-Z]{3}(?!!)(with CASE_INSENSITIVE) と[A-Za-z]{3}(?!!)で少なくとも 1 つの一致が"blah/ABC!/blah"見つかる ( bla2 回見つかる) ためです。

簡単なテストはこれを示しています:

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 に答える
1

完全な文字列内にパターンに一致する部分文字列があるため、これら 2 つは false 値をスローしません。具体的には、文字列blahは正規表現 (感嘆符が続かない 3 文字) と一致します。大文字ではないため、大文字と小文字を区別するものは正しく失敗しblahます。

于 2011-02-17T22:32:35.623 に答える