JS RegEx Doesn Not Match Even If It Should
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
- '2017-08-31 18_57_42-shouldwork.png' matches 2nd as expected
- '2017-08-31 18_57_43-shouldwork.png' does not match either
- '2017-08-31 18_57_42-shouldwork - Kopie.png' matches 2nd as expected
- '2017-08-31 18_57_42-shouldwork2.png' does not match
- '2019-03-09 11_11_09 - shouldwork - 000003.png' matches 1st as expected
- '2019-03-09 11_11_10 - shouldwork - 000003.png' matches 2nd
- '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.
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.
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM