Is there any better solution to this here? I try to avoid the assignment inside while
but still be able to loop through the matches and use the captured groups.
var match = "";
var CSS_URL_PATTERN = /url\s*\(\s*["|']?(.*?)\s*["|']?\)\s*/gm
while ((match = CSS_URL_PATTERN.exec(someBigCSSString)) !== null) {
// Do stuff here per match…
}
I added a bit more context to this question, also a RegEx example.
Is there any better solution to this here? I try to avoid the assignment inside while
but still be able to loop through the matches and use the captured groups.
var match = "";
var CSS_URL_PATTERN = /url\s*\(\s*["|']?(.*?)\s*["|']?\)\s*/gm
while ((match = CSS_URL_PATTERN.exec(someBigCSSString)) !== null) {
// Do stuff here per match…
}
I added a bit more context to this question, also a RegEx example.
Share Improve this question edited Aug 3, 2015 at 5:41 asked Aug 2, 2015 at 21:09 user2983883user2983883 5 |7 Answers
Reset to default 3I always do as follows when I need .exec
:
var re = /.../g, match;
while (match = re.exec(...)) {
//...
}
Regular expressions with g
flag causes infinite effect when it is in the loop condition.
What are the differences between Fx 3.x and Fx 4.x that made many userscripts stop working?
If you want to avoid the assignment inside while
you can use a do while
loop:
var URLRegExp = /url\s*\(\s*["|']?(.*?)\s*["|']?\)\s*/g
var match
do {
match = URLRegExp.exec(bootstrap)
if (match) {
// Do stuff here per match...
}
} while (match)
But a while loop
it's simpler and avoids unnecesary code like the if
statement inside do
. An assignment inside a condition is not as bad as people think if you understand what's the behaviour of the code and what's the context.
Another case is when you're using a linter to avoid to mistype a comparison operator (such as ==) as an assignment operator, but allmost all the linters using now support using comments to modify linter behaviour in a specific part of the code so this isn't really a problem
In 2023 String.prototype.matchAll works as an alternative to the while loop:
const CSS_URL_PATTERN = /url\s*\(\s*["|']?(.*?)\s*["|']?\)\s*/gm
[...someBigCSSString.matchAll(CSS_URL_PATTERN)].forEach(match => {
// Do stuff here per match…
});
var match = "Is This The Real Life|Is This Just Fantasy|Caught In A Landslide|No Escape From Reality|".match(/.+?\|/ig);
//print result using join
document.body.innerHTML += match.join("<br />");
document.body.innerHTML += "<br /><br />";
//print results using for loop and strip |
for (var i = 0; i < match.length; ++i)
{
document.body.innerHTML += match[i].slice(0, -1) + "<br />";
}
This will avoid a loop altogether. match
returns an array. You can either loop it and do stuff with it, or like I did print the results using join. match
accepts regex-patterns
.
var matches = someString.match(REGEX_PATTERN);
for (var i = 0; matches && i < matches.length; i++) {
// Do stuff here per match…
}
someString.replace(REGEX_PATTERN,
function (wholeMatch, group1, group2/*...*/, index, sourceString) {
// Do stuff here per match…
});
A few years later...
const URLRegExp = /url\s*\(\s*["|']?(.*?)\s*["|']?\)\s*/g;
for (;;) {
const match = URLRegExp.exec(bootstrap);
if (!match) break;
// Use the match
}
}
match
. It will return an array which you can loop. You way you designed it now will be an endless loop. – Mouser Commented Aug 2, 2015 at 21:13g
flag. In this case, it should be assigned outside loop. – w35l3y Commented Aug 2, 2015 at 21:57