Пересечение Java Regex (&&) не является коммутативным - PullRequest
0 голосов
/ 13 марта 2019

Оператор пересечения класса символов &&, по определению его функции, должен быть коммутативным. [a&&b] должно совпадать с теми же символами, что и [b&&a] для любых a и b. Я обнаружил, что все следующие шаблоны удовлетворяют этому критерию.

[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], это больше не так. Это выражение соответствует только c и d, но не a и b. Однако перевернутая версия [[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], но, тем не менее, документация подразумевает, что он должен работать. Это ошибка в реализации, или она действительно должна работать таким образом?

...