用正则表达式计算括号

时间:2013-09-09 16:53:39

标签: javascript regex

我的字符串是:(as(dh(kshd)kj)ad)... ()()

如何用正则表达式计算括号?我想选择从第一个开始括号开始并在...

之前结束的字符串

将其应用于上面的示例,这意味着我想获得此字符串:(as(dh(kshd)kj)ad)

我试着写它,但这不起作用:

var str = "(as(dh(kshd)kj)ad)... ()()";
document.write(str.match(/(.*)/m));

6 个答案:

答案 0 :(得分:3)

使用JavaScript正则表达式无法做到这一点。通常,正则表达式无法处理任意嵌套,因为常规语言无法再对其进行描述。

几种现代的正则表达式都有扩展,允许递归匹配(如PHP,Perl或.NET),但JavaScript不在其中。

答案 1 :(得分:3)

请参阅蒂姆的回答,说明为什么这不起作用,但这里的功能可以代替你做的事情。

function getFirstBracket(str){
  var pos = str.indexOf("("),
      bracket = 0;

  if(pos===-1) return false;

  for(var x=pos; x<str.length; x++){
    var char = str.substr(x, 1);    
    bracket = bracket + (char=="(" ? 1 : (char==")" ? -1 : 0));
    if(bracket==0) return str.substr(pos, (x+1)-pos);
  }
  return false;
}

getFirstBracket("(as(dh(kshd)kj)ad)... ()(");

答案 2 :(得分:3)

正如我在评论中所说的那样,与普遍的看法相反(不要相信人们所说的一切)与正则表达式匹配的嵌套括号

使用它的缺点是你可以只能达到固定的嵌套级别。对于您希望支持的每个额外级别,您的正则表达式将越来越大。

但是不要相信我的话。让我演示给你看。正则表达式\([^()]*\) matches one level。最多两级see the regex here。为了符合您的情况,您需要:

\(([^()]*|\(([^()]*|\([^()]*\))*\))*\)

它会与粗体部分匹配:(as(dh(kshd)kj)ad)... ()()

检查DEMO HERE并查看固定嵌套级别的含义。

等等。要继续添加关卡,您只需将最后[^()]*部分更改为([^()]*|\([^()]*\))*check three levels here)即可。正如我所说,它会变得越来越大。

答案 3 :(得分:3)

有可能,你的方法非常好: 如果你有一些命中,匹配将给你一个数组,如果是这样你可以查找数组长度。

var str = "(as(dh(kshd)kj)ad)... ()()",
    match = str.match(new RegExp('.*?(?:\\(|\\)).*?', 'g')),
    count = match ? match.length : 0;

此正则表达式将获取包含圆括号的文本的所有部分。有关优秀的在线正则表达式测试程序,请参阅http://gskinner.com/RegExr/

现在您可以对所有括号使用count。 match将提供如下所示的数组:

["(", "as(", "dh(", "kshd)", "kj)", "ad)", "... (", ")", "(", ")"]

现在您可以开始对结果进行排序:

var newStr = '', open = 0, close = 0;

for (var n = 0, m = match.length; n < m; n++) {
    if (match[n].indexOf('(') !== -1) {
        open++;
        newStr += match[n];
    } else {
        if (open > close) newStr += match[n];
        close++;
    }
    if (open === close) break;
}

...而newStr将是(as(dh(kshd)kj)ad)

这可能不是最好的代码,但它会让你更容易理解你在做什么。

使用这种方法,嵌套级别没有限制。

答案 4 :(得分:2)

没有。正则表达式表达常规语言。有限自动机(FA)是识别常规语言的机器。顾名思义,FA在记忆中是有限的。在有限的记忆中,FA无法记住任意数量的括号 - 这是为了做你想做的事所需要的功能。

我建议您使用涉及枚举器的算法来解决您的问题。

答案 5 :(得分:1)

试试这个jsfiddle

var str = "(as(dh(kshd)kj)ad)... ()()";
document.write(str.match(/\((.*?)\.\.\./m)[1] );