Negative lookaheads might not work due to prior greediness

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the regex category.

Last Updated: 2024-04-25

I wanted to match files ending in .js but not ones ending in .spec.js

e.g to match users.js but not users.spec.js

My first draft using a negative lookahead revealed a misunderstanding about lookaheads:

/\w+(?!spec)\.js/

When called on users.spec.js it returned spec.js - i.e. the \w+ bit captured spec despite the negative lookahead asking not to include that bit. Essentially the issue was that the negative lookahead applied only after the \w+

To understand more:

Another, probably easier way to get it to work, is to rewrite with a negative lookbehind:

/\w+(?<!spec)\.js$/

Lesson

Watch out for prior greediness crowding out negative lookahead. Consider replacing problematic parts with negative look-behinds.