Ad

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) https://jsfiddle.net/sfwr750n/
and here is a link to regex101 https://regex101.com/r/dxGFNN/1

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.

Ad

Answer

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.

Ad
source: stackoverflow.com
Ad