Alex Turpin
Alex Turpin

Reputation: 47776

Making part of JavaScript regex optional

I have the following original strings:

# Original strings
js/main_dev.js # This one is just to check for false positives
js/blog/foo.js
js/blog/foo.min.js

I'd like to run a substitution regex on each one and end up with this:

# Desired result
js/main_dev.js
js/blog/foo_dev.js
js/blog/foo_dev.min.js

So basically, add _dev before .min.js if it exists, if not, before .js. That should only apply on strings that start with js/blog or js/calculator and end in .js.

I initially started out with (js\/(?:blog|calculators)\/.+)(\.min\.js)$ as a regex and then $1_dev$2 as substitution. That works for my third string, but not my second obviously as I am "hard" looking for .min.js. So I figured I'd make .min optional by throwing it in a non capture group with a ? like this: (js\/(?:blog|calculators)\/.+)((?:\.min)?\.js)$. Now this works for my second string but my third string is all out of whack:

js/main_dev.js # Good
js/blog/foo_dev.js # Good
js/blog/foo.min_dev.js # Bad! _dev should be before the .min

I've tried many permutations on this, including simply doing (\.min\.js|\.js) but to no avail, all result in the same behavior. Here is a Regex 101 paste with the "bad" regex: https://regex101.com/r/bH3yP6/1

What am I doing wrong here?

Upvotes: 1

Views: 5374

Answers (1)

John
John

Reputation: 2425

Try throwing a ? after the + at the end of your first group (the non-capturing one) to make it lazy (non-greedy):

(js\/(?:blog|calculators)\/.+?)((?:\.min)?\.js)$

(?:\.min)? is optional and .+ is greedy, so .+ was capturing .min.

https://regex101.com/r/bH3yP6/3

Upvotes: 8

Related Questions