0

Consider I have a URL need to match, which may or may not include the query parameter enforceLogin.

To find whether enforceLogin is exist in URL, I wrote regexp like this:

/(enforceLogin=(\d+))?/.exec('something?enforceLogin=1')

I hope it could be matched but it returns

["", undefined, undefined]

But after I add $ to the end of the regexp or remove the ? at the end of regexp, it matched correctly.

Here comes the question, why the first regexp could not work? The string actually has enforceLogin=1 in it.

And if the question mark in the tail of regexp makes it lazier to match the content, why add $ to the end makes it work again?

Sunny
  • 127
  • 7
  • 4
    `?` means to match 0 or 1 repetitions of the pattern. It matched 0 repetitions at the beginning of the string. – Barmar Oct 13 '16 at 08:18
  • 2
    When you add the `$` anchor, it can't match at the beginning. It has to find something at the end, and then it finds the match. – Barmar Oct 13 '16 at 08:19
  • 1
    @Barmar: There's an answer there, which is basically: Add the `$` but don't remove the `?`: `/(enforceLogin=(\d+))?$/.exec('something?enforceLogin=1')` (combined with your excellent explanations). – T.J. Crowder Oct 13 '16 at 08:20
  • 2
    In general, an optional group is only useful if it's next to something else that has to be matched. – Barmar Oct 13 '16 at 08:20
  • See http://stackoverflow.com/documentation/regex/1603/anchor-characters-dollar. Also, for more details about `?` see http://stackoverflow.com/questions/17400048/how-does-the-make-a-quantifier-lazy-in-regex/17400486#17400486 – Wiktor Stribiżew Oct 13 '16 at 08:23
  • Since there is no problem with your solution, the question is only asking for clarification of `?` and `$` and is a dupe of [*Reference - What does this regex mean?*](http://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean). Those are basic regex special metacharacters already dealt with in detail on SO, see the links I provided. – Wiktor Stribiżew Oct 13 '16 at 08:27
  • @WiktorStribiżew Actually I've checked the link you provided before ask this question, the answer I want to know is how regex engine match the pattern, like the comment written by Barmar. – Sunny Oct 13 '16 at 09:44
  • The first comment? The same can be easily seen at regex101.com. It tells you that `$` asserts the position at the end of string and `?` matches 1 or 0 occurrences of the quantified subpattern. – Wiktor Stribiżew Oct 13 '16 at 09:47
  • @Barmar Thanks for your comment! I want to ask a bit more since I change it to `/.+(enforceLogin=(\d+))?/.exec('something?enforceLogin=1')`, the result return changed to `["something?enforceLogin=1", undefined, undefined]`, seems it had been matched but things I expected is `["something?enforceLogin=1", "enforceLogin=1", "1"]`, why it still not correct? – Sunny Oct 13 '16 at 09:49
  • Because `.+` tries to match the longest string possible, so it matches the whole string. Then there's nothing left over to match the optional group. – Barmar Oct 13 '16 at 09:55
  • Making it non-greedy with `.+?` doesn't help. Then `.+?` matches the first character of the string, and the optional group matches nothing right after that. Optional groups need to be next to something specific. – Barmar Oct 13 '16 at 09:58
  • Hi @WiktorStribiżew, I'm not a newbie to regexp and I know all regex rules. Also I know this question seems stupid but I really cannot imagine why engine do the match like this. Sorry for the stupid question :) – Sunny Oct 13 '16 at 09:59
  • Why are you making it optional in the first place? If you want to know if `enforceLogin` is in the URL, just search for it normally. If the regexp matches, then it's in there. – Barmar Oct 13 '16 at 09:59
  • Even for experienced people, some of this stuff is confusing. regex101.com is useful, it will show you how each part of the regexp fits into the input string. – Barmar Oct 13 '16 at 10:02
  • See https://regex101.com/r/2QbEjg/1 – Barmar Oct 13 '16 at 10:03
  • The regexp engine doesn't try to find a match that fills in all the optional groups. It just looks for anything that matches the rules. Since an optional group is allowed to match nothing, it won't put a constraint on what is matched by a quantifier next to it. – Barmar Oct 13 '16 at 10:05
  • @Barmar Thanks! I will remember optional groups need to be next to something specific. It's not used in any production code, just some test code write in console but makes me confused in a whole day. – Sunny Oct 13 '16 at 10:07

0 Answers0