4

My web application needs to parse numeric ranges in strings that are enclosed by parenthesis. I've never really understood regex properly so I need some assistance. The code below is kind of what I'm looking to do (I'll then split the string on the hyphen and get the min/max values). Obviously the pattern is wrong - the example below alerts "(10-12) foo (5-10) bar" when my desired result is 1 alert saying (10-12) and the next saying (5-10), or better yet those values without the parenthesis if that's possible.

Any assistance is appreciated.

var string = "foo bar (10-12) foo (5-10) bar";
var pattern = /\(.+\)/gi;
matches = string.match(pattern);

for (var i in matches) {
    alert(matches[i]);
}
1

2 Answers 2

9

Make your quantifier lazy by adding a ? after the +. Otherwise, it will greedily consume as much as possible, from your opening ( to the last ) in the string.

var string = "foo bar (10-12) foo (5-10) bar",
    pattern = /\(.+?\)/g,
    matches = string.match(pattern);

jsFiddle.

If you don't want to include the parenthesis in your matches, generally you'd use a positive lookahead and lookbehind for parenthesis. JavaScript doesn't support lookbehinds (though you can fake them). So, use...

var string = "foo bar (10-12) foo (5-10) bar",
    pattern = /\((.+?)\)/g,
    match,
    matches = [];

while (match = pattern.exec(string)) {
    matches.push(match[1]);
}

jsFiddle.

Also...

  • You don't need the i flag in your regex; you don't match any letters.
  • You should always scope your variables with var. In your example, matches will be global.
  • You shouldn't use a for (in) to iterate over an array. You should also check that match() doesn't return null (if no results were found).
Sign up to request clarification or add additional context in comments.

6 Comments

Excellent - is there a way to remove the parenthesis on the matches too or is that better handled outside of regex?
@user949738 Certainly, see the part of my answer I'm about to write :)
@user949738: string.match(/\(.+?\)/g).join('').match(/\d+\-\d+/g)
@KooiInc Interesting. You shouldn't need to escape the - in the last regex.
@alex: you're right. Anyway, if you want to check whilst there are no numeric values between parenthesis in the string to check you can still keep it on one line: (string.match(pattern)||[]).join('').match(/(\d+-\d+)/g);
|
4

The problem is that your regular expression is Greedy, meaning that it will match the first bracket and keep on going till it finds the last bracket. To fix this you have two options, you either add the ? symbol after the + to make it non greedy: \(.+?\) or else, match any character except a closing bracket: \([^)]+\).

Both of these regular expressions should do what you need.

1 Comment

This solution is a better one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.