最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Better solution to regex.exec() assignment in while loop - Stack Overflow

programmeradmin0浏览0评论

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
  • 1 Why not use 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:13
  • What are you trying to do in this loop? – eddyjs Commented Aug 2, 2015 at 21:14
  • "avoid the assignment inside while" - why? you can avoid it but it's really not that bad. – dfsq Commented Aug 2, 2015 at 21:17
  • It won't work properly whether it has g flag. In this case, it should be assigned outside loop. – w35l3y Commented Aug 2, 2015 at 21:57
  • @dfsq Not sure about that. The only reason I can think of is that the assignment '=' can be easily misread with a comparison '==='. It simply doesn't feel right tbh and ESLint complains about it (no-cond-assign). – user2983883 Commented Aug 3, 2015 at 5:51
Add a comment  | 

7 Answers 7

Reset to default 3

I 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
  }
}
发布评论

评论列表(0)

  1. 暂无评论