Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count parentheses with regular expression

My string is: (as(dh(kshd)kj)ad)... ()()

How is it possible to count the parentheses with a regular expression? I would like to select the string which begins at the first opening bracket and ends before the ...

Applying that to the above example, that means I would like to get this string: (as(dh(kshd)kj)ad)

I tried to write it, but this doesn't work:

var str = "(as(dh(kshd)kj)ad)... ()()";
document.write(str.match(/(.*)/m));
like image 240
don kaka Avatar asked Sep 09 '13 16:09

don kaka


2 Answers

As I said in the comments, contrary to popular belief (don't believe everything people say) matching nested brackets is possible with regex.

The downside of using it is that you can only do it up to a fixed level of nesting. And for every additional level you wish to support, your regex will be bigger and bigger.

But don't take my word for it. Let me show you. The regex \([^()]*\) matches one level. For up to two levels see the regex here. To match your case, you'd need:

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

It would match the bold part: (as(dh(kshd)kj)ad)... ()()

Check the DEMO HERE and see what I mean by fixed level of nesting.

And so on. To keep adding levels, all you have to do is change the last [^()]* part to ([^()]*|\([^()]*\))* (check three levels here). As I said, it will get bigger and bigger.

like image 94
acdcjunior Avatar answered Sep 22 '22 12:09

acdcjunior


See Tim's answer for why this won't work, but here's a function that'll do what you're after instead.

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)... ()(");
like image 42
Doug Avatar answered Sep 20 '22 12:09

Doug