JS RegEx Doesn Not Match Even If It Should

- 1 answer

I'm writing a node.js script to group tons of screenshots.
I have got two different patterns that I want to match:

/(?<date>\d{4}-\d{2}-\d{2}) (?<time>\d{2}_\d{2}_\d{2})(-| - )(?<window>.*?)(-| - )(?<index>\d{6})(?<extension>\.(png|jpg|jpeg))/g
/(?<date>\d{4}-\d{2}-\d{2}) (?<time>\d{2}_\d{2}_\d{2})(-| - )(?<window>.*?)(?<extension>\.(png|jpg|jpeg))/g
  1. '2017-08-31 18_57_42-shouldwork.png' matches 2nd as expected
  2. '2017-08-31 18_57_43-shouldwork.png' does not match either
  3. '2017-08-31 18_57_42-shouldwork - Kopie.png' matches 2nd as expected
  4. '2017-08-31 18_57_42-shouldwork2.png' does not match
  5. '2019-03-09 11_11_09 - shouldwork - 000003.png' matches 1st as expected
  6. '2019-03-09 11_11_10 - shouldwork - 000003.png' matches 2nd
  7. 'should fail.png' does not match either as expected

Here is also fiddle where you can see it with my code (reduced to the problematic parts)
and here is a link to regex101

At first I thought it was just node.js, but Chrome has the same problem (didn't try firefox, last time I checked it didn't support named groups), even more confusing is the fact that regex101 matches everything as expected.



Your regular expressions use the g flag, which means that they retain state. For instance, you've said your second string doesn't match either of your expressions, but it does, provided the expression is starting at the beginning:

const rex = /(?<date>\d{4}-\d{2}-\d{2}) (?<time>\d{2}_\d{2}_\d{2})(-| - )(?<window>.*?)(?<extension>\.(png|jpg|jpeg))/g;
const str = "2017-08-31 18_57_43-shouldwork.png";
console.log(rex.exec(str)); // Works
console.log(rex.exec(str)); // Fails
.as-console-wrapper {
  max-height: 100% !important;

I'd suggest that you don't use the g flag, and do use anchors at the beginning and end so you're matching the entire string. Alternately, if you're looking for these strings within a larger block of text, just be sure to set lastIndex = 0 on the regular expression when starting to search a new block of text so it doesn't continue from where it previously left off.