Question

I'm working with a regex in javascript.

I have this regex: /\/.+?$/

and this string: /path/to/file

I am expecting to get /file as a result but instead am getting the entire string back. What am I not understanding here? The ? should make the + non-greedy, meaning it will match the fewest possible characters.

Was it helpful?

Solution

Regular expressions will always try to match left to right. Even though .+? is non-greedy, the regex will still try to match from the beginning of the string if possible and only advance the starting position when the match fails.

You have a couple of options to fix this:

  • Include a greedy match at the beginning of the regex so that your match will always start as far into the string as possible, and use a capturing group to grab what you want. The regex here might looks something like /.*(\/.+?)$/, and then you would get /file as the contents in the first capturing group.
  • Change the regex so that the .+? can't match any additional /, so it would be /\/[^\/]+$/.

OTHER TIPS

You can use negation for your need:

'/path/to/file'.match(/\/[^/]+$/);
//=> ["/file"]

Your regex /\/.+?$/ is matching first slash and then matching rest of the input using .+? since there is nothing following .+?.

You can see different behavior if you use: /\/.+?\/$/ which will behave reluctantly and match /path/.

The $ at the end of your expression forces a compulsory end-of-string match. The only way to do so is to grab the entire string, greedy or not.

However, your regex is flawed even without the $. /\/.+?/ will match just one character, where the entire string is matched by /\/.+/. You don't specify any constraint at all.

To grab only the first part, up to -- but excluding -- a next slash, use this:

/\/.[^\/]*/
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top