-2

Assume the following code:

"ab00ab____ab01ab".match(/ab(.+)ab/);

I want this to get me 00 and 01, but instead it returns me this:

["ab00ab____ab01ab", "00ab____ab01"]

How can I fix this problem?

Lucas
  • 16,930
  • 31
  • 110
  • 182
  • [Like in this thread](http://stackoverflow.com/questions/39200657/how-do-you-match-valid-integers-and-roman-numerals-with-a-regular-expression?noredirect=1#comment65741443_39200657), I am bound to comment that just accessing the capture groups is not fixing the current problem and the question cannot be closed with [*JavaScript Regular Expressions and Capture Groups*](http://stackoverflow.com/questions/33621271/javascript-regular-expressions-and-capture-groups). – Wiktor Stribiżew Aug 30 '16 at 10:36
  • Does my answer clear the problem? – Wiktor Stribiżew Aug 30 '16 at 15:48

1 Answers1

1

Use RegExp#exec inside a loop with the /ab(.+?)ab/g regex:

var s = "ab00ab____ab01ab";
var re = /ab(.+?)ab/g;
var res = [];
while ((m=re.exec(s)) !== null) {
  res.push(m[1]);
}
console.log(res);

First of all, you need a lazy dot matching pattern (.*? or .+?) to match up to the first ab, not a greedy one (.+) matching up to the last ab. Also, with String#match and a regex with a global modifier, you lose all the captures (those substrings matched with the parenthesized regex pattern parts), you can only have them with the RegExp#exec.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • @MarioAlexandroSantini: You are wrong, because my regex does not match an empty string. After each successful match the `lastIndex` property of the `RegExp` class is automatically advanced. If there is no match, `m` is *null*. – Wiktor Stribiżew Aug 30 '16 at 10:31
  • The issue is not when you have an empty string. In this case you just skip the while. I was thinking that *re.exec()* was always matching as results in an infinite loop. Anyway, your code is dangerous, as if you remove the *g* flag from the regular expression you have an infinite loop. – Mario Santini Aug 30 '16 at 11:23
  • @MarioAlexandroSantini: If I were to remove the `/g` from the regex, I would not be using `RegExp.exec` *because if you are using a regex without a global modifier with `RegExp#exec` the `lastIndex` property will not be advanced automatically*. You should have read about the [`RegExp#exec`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec) behavior before posting these comments. You are making wrong assumptions, this code is totally safe **and it cannot run into an infinite loop**. – Wiktor Stribiżew Aug 30 '16 at 11:25
  • This is the point, in your example, everything is fine as is just few line of code. In real world code, the regular expression could be assigned dynamically or hundred or thousand of lines of code away from which you use. So could be not so obvious that the removing of the *g* flag will results in a infinite loop. This because regexp are changed with the input data. But is just a consideration on more strong code. Anyway thanks because I learned a new think today. – Mario Santini Aug 30 '16 at 11:34
  • If OP mentions anything about the pattern re-use, I will recommend something different. Right now, the solution is tailored for the current task. – Wiktor Stribiżew Aug 30 '16 at 11:44