0

文字クラス交差演算子&&は、その関数の定義により可換でなければなりません。a および b と[a&&b]まったく同じ文字に一致する必要があります。[b&&a]次のパターンはすべてこの基準を満たしていることがわかりました。

[a-z&&abcd]と同じ[abcd&&a-z]

[a-z&&ab[cd]]と同じ[ab[cd]&&a-z]

[a-z&&[ab][cd]]と同じ[[ab][cd]&&a-z]

それらはすべて と同等[abcd]です。ただし、 と表現する[a-z&&[ab]cd]と、これは当てはまりません。その式は and のみに一致し、 candには一致しdません。ただし、反転バージョンは、他のパターンと同様に 4 つの文字すべてに一致します。言い換えるとab[[ab]cd&&a-z]

[[ab]cd&&a-z]と同じではない[a-z&&[ab]cd]

Patternこれがなぜなのかを調べるために のソースを調べたところ、これが交差の実装方法であることがわかりました (Java 1.8.0_60 JDK)

case '&':
    // ...
    ch = next();
    if (ch == '&') {
        ch = next();
        CharProperty rightNode = null;
        while (ch != ']' && ch != '&') {
            if (ch == '[') {
                if (rightNode == null)
                    rightNode = clazz(true);
                else
                    rightNode = union(rightNode, clazz(true));
            } else { // abc&&def
                unread();
                rightNode = clazz(false); // here is what happens
            }
            ch = peek();
        }

マークされた行が

rightNode = clazz(false);

そしてそうではない

rightNode = union(rightNode, clazz(true));

つまり、 の右側で&&は、ネストされた文字クラス内にない最初の文字が検出されるたびに、パターン パーサーはその前に何もないと見なします。そのため、 の後&&、パーサーは を読み取り[ab]rightNode次に を読み取りますcdが、 とマージする代わりに、[ab]上書きするだけです。

のような正規表現を実際に書く人はいないことは知っています[a-z&&[ab]cd]が、それでもドキュメントはそれが機能するはずであることを暗示しています。これは実装のバグですか、それとも実際にこのように動作するはずですか?

4

0 に答える 0