正则表达式,单一匹配 - 递归与子程序调用

时间:2018-01-01 10:31:41

标签: regex recursion subroutine

一个常见的现实世界用途是匹配一组平衡的括号。

\((?>[^()]|(?R))*\)匹配一对括号,其间包含任意文本,包括无限数量的括号,只要它们都正确配对即可。 (...)

如果你想要一个在包含不平衡括号的字符串中找不到任何匹配的正则表达式,那么你需要使用子程序调用而不是递归。 (这是我不理解的 - >)。如果要查找多对平衡括号的序列作为单个匹配,则还需要子例程调用。

所以使用"(?R)"不会产生"单一比赛"。它是否与单个匹配"不同,在一场比赛中有多个匹配?

来源: https://www.regular-expressions.info/recurse.html

"匹配平衡结构"一部分。

2 个答案:

答案 0 :(得分:0)

  

如果你想找到一对多对平衡的序列   括号作为单个匹配,那么您还需要一个子程序调用。

我相信这就是说如果你想匹配这个(.)(.) - 一对多对平衡括号的序列 - 那么你需要使用子程序。我承认,一个例子对本教程有帮助。

为什么递归无法返回“单个匹配”?这仅仅是因为递归的工作方式 - 它将相同的正则表达式应用于不断递减的字符串(如果它不是无限递归)并在到达非匹配元素时返回结果,然后沿着字符串继续前进。它不会将(.)(.)与单个字符串匹配,因为它没有定义为这样做(您可以使用量词来执行此操作:(?>\((?>[^()]|(?R))*\)){2}或更一般地:(?>\((?>[^()]|(?R))*\))*)。

以下是教程中为a sequence of multiple pairs of balanced parentheses(第1行)和for balanced constructs or nested constructs(第2行)生成的模式:

enter image description here

答案 1 :(得分:0)

我知道关于正则表达式和递归的这个问题。但如果您的原始任务是在括号之间找到匹配/不匹配,那么不使用正则表达式来执行此简单任务。可能更容易编写一条线条来解决这个问题:

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;
}
相关问题