Let\'s say I have the string
\"12345\"
If I .match(/\\d{3}/g), I only get one match, \"123\". Why don\'t I get
The string#match with a global flag regex returns an array of matched substrings. The /\d{3}/g regex matches and consumes (=reads into the buffer and advances its index to the position right after the currently matched character) 3 digit sequence. Thus, after "eating up" 123, the index is located after 3, and the only substring left for parsing is 45 - no match here.
I think the technique used at regex101.com is also worth considering here: use a zero-width assertion (a positive lookahead with a capturing group) to test all positions inside the input string. After each test, the RegExp.lastIndex (it's a read/write integer property of regular expressions that specifies the index at which to start the next match) is advanced "manually" to avoid infinite loop.
Note it is a technique implemented in .NET (Regex.Matches), Python (re.findall), PHP (preg_match_all), Ruby (String#scan) and can be used in Java, too.
Here is a demo using matchAll:
var re = /(?=(\d{3}))/g;
console.log( Array.from('12345'.matchAll(re), x => x[1]) );
Here is an ES5 compliant demo:
var re = /(?=(\d{3}))/g;
var str = '12345';
var m, res = [];
while (m = re.exec(str)) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
res.push(m[1]);
}
console.log(res);
Here is a regex101.com demo
Note that the same can be written with a "regular" consuming \d{3} pattern and manually set re.lastIndex to m.index+1 value after each successful match:
var re = /\d{3}/g;
var str = '12345';
var m, res = [];
while (m = re.exec(str)) {
res.push(m[0]);
re.lastIndex = m.index + 1; // <- Important
}
console.log(res);