0

以下の私の正規表現は、長さが8〜10の大文字の単語を除外することになっています。ここで0〜2の数字が表示される場合があります。それは私のすべてのテストで機能していますが、何らかの理由で下の文字列に引っかかってしまいました。そしてn.group(0)、一致した「単語」の代わりに空の文字列のみが含まれます。

static final Pattern PATTERN = 
    Pattern.compile("\\b(?=[A-Z\\d]{9,10}\\b)(?:[A-Z]*\\d){0,2}[A-Z]*\\b");

Matcher n = LONG_PASSWORD.matcher("foo ID:636152727 bar");

while (n.find()) {
    String s = n.group(0);                  
    resultArrayList.add(s);
}

パターンが一致するのはなぜID:636152727ですか?

私が除外したいいくつかの例(これは機能しています):

  • AAAAAAAAAA
  • 1AAAAAAAAA
  • 1AAAAAAAA1

等...

4

2 に答える 2

2

Ωmegaの答えよりも良い解決策はありませんが、何が起こっているのかを説明できると思います。つまり、最初\bと最後\bが同じ場所、つまりコロンの直後に一致しているということです。

これは、先読みが一致する最初の場所です。これは、9桁の数字と単語の境界が後に続くためです。次に、正規表現の次の部分は、2桁の数字(任意の数の大文字が点在)とそれに続く単語の境界を一致させようとし、失敗します。したがって、1桁(同上)だけを一致させようとし、再び失敗します。次に、ゼロ桁(ゼロ文字が点在)の一致を試み、一致位置を進めずに成功します。その位置はまだ単語の境界なので、決勝戦\bも成功します。

単語の境界は、先読みや後読みのように、幅がゼロのもう1つのアサーションです。2つ以上を同じ場所に適用できない理由はありません。あなたは最初の単語の境界と先読みで意図的にそれをしました。一部の正規表現フレーバーは、アサーションに数量詞\b+を適用するとエラーとして処理しますが(のように)、これらのいずれもこの問題をキャッチするとは思われません。\<これは、GNUや\>TCLなどの個別の単語の開始アサーション\yと単語の終わりアサーション\Yが違いを生むまれな例の1つです。

于 2012-11-27T23:41:34.437 に答える
1

^アンカーを 使用する必要があります$»

Pattern.compile("^(?=[A-Z\\d]{9,10}$)(?:[A-Z]*\\d){0,2}[A-Z]*$");

次のパターンを使用します。

"(?:^|(?<=\\s))(?=[A-Z\\d]{9,10}(?:\\s|$))(?:[A-Z]*\\d){0,2}[A-Z]*(?=\\s|$)"
于 2012-11-27T21:50:54.017 に答える