5

I have found a regex template in Expresso, this one works fine and returns perfect matches but in JavaScript it doesn't work. I know its may be for look-behind, but I am not enough efficient in Regex to make it JS compatible.

\((?>[^()]+|\((?<number>)|\)(?<-number>))*(?(number)(?!))\)

I want to match it with ...

max(50, max(51, 60)) a() MAX(s,4,455)something

... and it should return ...

1: (50, max(51, 60))

2: ()

3: (s,4,455)

This works perfectly in Expresso but JS console in Chrome says:

Uncaught SyntaxError: Invalid regular expression: /\((?>[^()]+|\((?<number>)|\)(?<-number>))*(?(number)(?!))\)/: Invalid group

How can this regex be modified to function properly in JavaScript?

entropo
  • 2,398
  • 15
  • 15
Muhammad Usman
  • 11,962
  • 6
  • 34
  • 56

4 Answers4

6

JavaScript does not support named capture groups (?<number>)

As suggested in this question, regex may not be the right tool for the job. However, if you simply want to match the outermost parenthesized groups you can use this

/\([^)]*(\s?\))*\)/g

See it working at http://refiddle.com/114

Community
  • 1
  • 1
Paul Alexander
  • 30,715
  • 14
  • 93
  • 146
  • Thanks Paul, it works in the given string but doesn't return expected result in different string. AVG(ROUND(5,8),10,11)*MAX(MAX(5),10,AVG(5)) Any suggestion? – Muhammad Usman May 04 '11 at 16:39
  • Yeah, regex doesn't really handle nesting very well. You might be better off writing a tokenizer and parsing the string manually yourself instead of using regex. – Paul Alexander May 04 '11 at 16:48
4

Assuming that your given regular expression is a .NET regular expression, the following syntax components are not supported by JavaScript:

To get the same result with JavaScript, you’ll need to do the balancing on your own:

var parts = str.match(/[()]|[^()]+/g),
    matches = [],
    balance = 0;
for (var i=0, j=0; i<parts.length; i++) {
    switch (parts[i]) {
    case "(":
        if (balance === 0) {
            j = i;
        }
        balance++;
        break;
    case ")":
        if (balance === 1) {
            matches.push(parts.slice(j, i+1).join(""));
        }
        balance--;
        if (balance < 0) {
            throw new EvalError('parentheses are not balanced; unexpected "("');
        }
        break;
    }
}
if (balance > 0) {
    throw new EvalError('parentheses are not balanced; missing ")"');
}
Gumbo
  • 594,236
  • 102
  • 740
  • 814
2

There's no negative lookbehind in Javascript. You'll have to find an alternative.

Edit: I looked at your RegEx again, and I thought I saw negative lookbehind, but I guess I didn't. I'll leave this for informational purposes anyways.

Matt Kellogg
  • 1,213
  • 7
  • 15
0

In javascript, numbers can be defined with [0-9] or \d Not a digit is [^0-9] or \D

Plahcinski
  • 335
  • 2
  • 6