【问题标题】:Removing unnecessary parentheses in a regular expression删除正则表达式中不必要的括号
【发布时间】:2011-02-28 17:00:18
【问题描述】:

假设我有(在 javascript 正则表达式中)

((((A)B)C)D)

当然真的是这样

ABCD

有没有一种算法可以消除字符串中不必要的括号?

【问题讨论】:

  • 你怎么知道它们是不必要的?他们正在捕获组,代码可能依赖于他们的存在。

标签: javascript regex boost-regex


【解决方案1】:

此函数将删除所有后面没有量词且不是环视的组。它假定 ECMAScript 风格的正则表达式,并且捕获组 (( ... )) 并不重要。

function removeUnnecessaryParenthesis(s) {
   // Tokenize the pattern
   var pieces = s.split(/(\\.|\[(?:\\.|[^\]\\])+]|\((?:\?[:!=])?|\)(?:[*?+]\??|\{\d+,?\d*}\??)?)/g);
   var stack = [];
   for (var i = 0; i < pieces.length; i++) {
      if (pieces[i].substr(0,1) == "(") {
         // Opening parenthesis
         stack.push(i);
      } else if (pieces[i].substr(0,1) == ")") {
         // Closing parenthesis
         if (stack.length == 0) {
            // Unbalanced; Just skip the next one.
            continue;
         }
         var j = stack.pop();
         if ((pieces[j] == "(" || pieces[j] == "(?:") && pieces[i] == ")") {
             // If it is a capturing group, or a non-capturing group, and is
             // not followed by a quantifier;
             // Clear both the opening and closing pieces.
             pieces[i] = "";
             pieces[j] = "";
         }
      }
   }
   return pieces.join("");
}

例子:

removeUnnecessaryParenthesis("((((A)B)C)D)")  --> "ABCD"
removeUnnecessaryParenthesis("((((A)?B)C)D)") --> "(A)?BCD"
removeUnnecessaryParenthesis("((((A)B)?C)D)") --> "(AB)?CD"

它不会尝试确定括号是否仅包含单个标记 ((A)?)。这将需要更长的标记模式。

【讨论】:

    【解决方案2】:

    1) 使用理解括号的解析器

    2) 使用可以匹配括号的 Perl 递归正则表达式(在这种情况下不鼓励恕我直言)我不认为 Boost 正则表达式支持所需的递归类型。

    3) 也许他们是需要的?别管他们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-14
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 2016-11-26
      • 2014-10-09
      • 1970-01-01
      相关资源
      最近更新 更多