RegExp spec question
expected by specs ... try this
r = /\u0020+$/g; p = r.exec(" "); r.lastIndex = 0; q = r.exec(" ");
alert(JSON.stringify([p, q]))
and you are good to go
... without resetting lastIndex, you can also use " ".replace(r, 'whatever')
and it's going to work every time.
Have a look at these slides to know more about JS RegExp
Yes, the /g flag is confusing, because the regular expression kind of turns into an iterator. I’d much prefer an actual iterator-based API that doesn’t mutate the regular expression.
You could wrap it in an iterator :-)
function* match(regex, haystack){
var {source, ignoreCase} = regex;
var newRegex = new RegExp(source, ignoreCase ? 'gi' : 'g');
var m = null;
while (m = newRegex.exec(haystack)) {
yield m;
}
}
var input = "I have 5 dogs, 3 cats, and 49 ants.";
for (let num of match(/\d+/, input)) {
console.log(num);
}
you can also use this code ... like today, with every browser, and right away ...
function match(regex, haystack){
var result = [], g = regex.global, match;
do { match = regex.exec(haystack) }
while(match && result.push(match) && g);
if (!g) regex.lastIndex = 0;
return result;
}
var input = "I have 5 dogs, 3 cats, and 49 ants.";
match(/\d+/, input)
match(/\d+/g, input)
Best
function* match(regex, haystack){ var {source, ignoreCase} = regex; var newRegex = new RegExp(source, ignoreCase ? 'gi' : 'g'); var m = null; while (m = newRegex.exec(haystack)) { yield m; } }
this code is not best in that case:
var regex = /\d+/;
var first = match(regex, "1 2 3 4"); var second = match(regex, "1 2 3 4"); first.next(); second.next(); // ?
r = /\u0020+$/g; p = r.exec(" "); q = r.exec(" "); JSON.stringify([p, q]) // "[[\" \"],null]"
Why does calling exec the second time generate null? When I try the regular expression without the /g flag, I get:
// "[[\" \"],[\" \"]]"