45

このパターンがコンパイルに失敗する理由:

Pattern.compile("(?x)[ ]\\b");

エラー

ERROR java.util.regex.PatternSyntaxException:
Illegal/unsupported escape sequence near index 8
(?x)[ ]\b
        ^
at java_util_regex_Pattern$compile.call (Unknown Source)

次の同等のものは機能しますか?

Pattern.compile("(?x)\\ \\b");
Pattern.compile("[ ]\\b");
Pattern.compile(" \\b");

これは Java 正規表現コンパイラのバグですか、それとも何か不足していますか? [ ]バックスラッシュ-バックスラッシュ-スペースの代わりに冗長な正規表現で使用するのが好きです。視覚的なノイズを節約できるからです。しかし、明らかにそれらは同じではありません!

PS: この問題はバックスラッシュに関するものではありません。[ ]バックスラッシュを使用する代わりに、単一のスペースを含む文字クラスを使用して、冗長な正規表現でスペースをエスケープすることです。

どういうわけか、冗長な正規表現(?x)と単一のスペースを含む文字クラスの組み合わせにより[ ]、コンパイラがオフになり、単語の境界エスケープが認識されなくなります\b


1.8.0_151 までの Java でテスト済み

4

5 に答える 5

5

正確に何が起こるかを分析しましょう。

java.util.regex.Patternのソース コードを見てください。

パターン内の空白とコメントを許可します。このモードでは、空白は無視され、# で始まる埋め込みコメントは行末まで無視されます。

コメント モードは、埋め込みフラグ式 (?x) を使用して有効にすることもできます。

あなたの正規表現はこの行にあなたを導きます

private void accept(int ch, String s) {
    int testChar = temp[cursor++];
    if (has(COMMENTS))
        testChar = parsePastWhitespace(testChar);
    if (ch != testChar) {
        throw error(s);
    }
}

コードがparsePastWhitespace(testChar);を呼び出していることに気づいたら、

private int parsePastWhitespace(int ch) {
    while (ASCII.isSpace(ch) || ch == '#') {
        while (ASCII.isSpace(ch))//<----------------Here is the key of your error
            ch = temp[cursor++];
        if (ch == '#')
            ch = parsePastLine();
    }
    return ch;
}

あなたの場合、正規表現に空白がある場合、(?x)[ ]\\bこれは何かを返します(正しく分析できません):

    if (ch != testChar) {
        throw error(s);
    }

これは等しくなくch、ここで例外は throws です

throw error(s);
于 2018-03-13T19:48:31.443 に答える