Обычное использование в реальном мире - сопоставление сбалансированного набора круглых скобок.

\((?>[^()]|(?R))*\) соответствует одной паре скобок с любым текстом между ними, включая неограниченное количество скобок, при условии, что все они правильно соединены. (...)

Если вам нужно регулярное выражение, которое не находит совпадений в строке, содержащей несбалансированные круглые скобки, вам нужно использовать вызов подпрограммы вместо рекурсии. (И ЭТО ЧТО Я НЕ ПОНИМАЮ ->). Если вы хотите найти последовательность из нескольких пар сбалансированных круглых скобок как одно совпадение, вам также понадобится вызов подпрограммы.

Таким образом, использование «(? R)» не приведет к «единственному совпадению». Это что-то отличное от «одного матча», что-то вроде нескольких совпадений в одном матче?

Источник: https://www.regular-expressions.info/recurse.html

Часть «Соответствие сбалансированным конструкциям».

0
user9098366 1 Янв 2018 в 13:31

2 ответа

Лучший ответ

Если вы хотите найти последовательность из нескольких пар сбалансированных круглых скобок как одно совпадение, вам также понадобится вызов подпрограммы.

Я считаю, что это означает, что если вы хотите сопоставить этот (.)(.) - последовательность из нескольких пар сбалансированных круглых скобок - тогда вам необходимо использовать подпрограммы. Признаюсь, в учебнике помог бы пример.

Почему рекурсия не возвращается «как одно совпадение»? Это просто из-за того, как работает рекурсия - она применяет одно и то же регулярное выражение к постоянно убывающей строке (если она не бесконечно рекурсивна) и возвращает результат, когда он достигает несовпадающего элемента, а затем продолжает движение по строке. Он не соответствует (.)(.) как отдельной строке, потому что он не определен для этого (вы можете сделать это с помощью квантификаторов: (?>\((?>[^()]|(?R))*\)){2} или, в более общем смысле: (?>\((?>[^()]|(?R))*\))*).

Вот что дает шаблон, представленный в руководстве, для a sequence of multiple pairs of balanced parentheses (строка 1) и for balanced constructs or nested constructs (строка 2):

enter image description here

0
Mindaugas Bernatavičius 1 Янв 2018 в 11:51

Я знаю, что это вопрос о регулярном выражении и рекурсии. Но если ваша первоначальная задача состоит в том, чтобы найти совпадения / не совпадения в круглых скобках, как насчет того, чтобы не использовать регулярное выражение для этой простой задачи. Наверное, для решения этой проблемы проще написать пару строк:

public static Map<Integer, Integer> findAllPairs(String str) {
    Map<Integer, Integer> map = new TreeMap<>();
    Deque<Integer> stack = new LinkedList<>();
    char[] symbols = str.toCharArray();

    for (int i = 0; i < symbols.length; i++) {
        if (symbols[i] == '(')
            stack.push(i);
        else if (symbols[i] == ')') {
            if (stack.isEmpty())
                throw new IllegalArgumentException("Not pair ')' at position " + i);
            map.put(stack.pop(), i);
        }
    }

    if (!stack.isEmpty())
        throw new IllegalArgumentException("Total " + stack.size() + " not pair '('");

    return map;
}
0
oleg.cherednik 1 Янв 2018 в 12:27