Regular expression matches to repeated part although I use a question mark

Viewed 49

I was needed to check if paths have correct names then I've created a regular expression as below:

^\/2\d{3}(\/2\d{3}-(0[1-9]|1[0-2])(\/[a-z ]+(\/(g|o)(\/[a-z ]+(\/s)?)?)?)?)?$

And it works for correct names but unfortunately, it also matches the wrong one like the next: /2020/2020-05/test/o/test. The last test is invalid I must decline this path.

Examples of correct paths:

  • /2020/2020-05/test/o
  • /2020/2020-05/test/o/s (maximum, a nothing can be yet at the end)
  • /2020/2020-05/test
  • /2020/2020-05
  • /2020

Examples of incorrect paths:

  • /2020/2020-05/test/o
  • /2020/2020/2020-05/test/o/smth
  • /2020/2020-05/test/test/o
  • /2020/2020-05/test/o/o/smth
  • and so on

But as I know the question mark matches zero or one time so I cannot get what's wrong with my expression. Can anyone explain me, plz?

P.S. I use Python regular expressions if it's important.

1 Answers

It appears you added the last but one optional group by mistake. You need to remove it:

^/2\d{3}(/2\d{3}-(0[1-9]|1[0-2])(/[a-z ]+(/[go](/s)?)?)?)?$

Or, using non-capturing groups for better performance:

^/2\d{3}(?:/2\d{3}-(?:0[1-9]|1[0-2])(?:/[a-z ]+(?:/[go](?:/s)?)?)?)?$

See the regex demo.

Pattern details

  • ^ - start of string
  • /2 - a /2 substring
  • \d{3} - three digits
  • (?:/2\d{3}-(?:0[1-9]|1[0-2])(?:/[a-z ]+(?:/[go](?:/s)?)?)?)? - an optional occurrence of
    • /2\d{3}- - /2 and then any three digits
    • (?:0[1-9]|1[0-2]) - either 0 and then any non-zero digit or 1 followed with 0, 1 or 2
    • (?:/[a-z ]+(?:/[go](?:/s)?)?)? - an optional occurrence of
      • /[a-z ]+ - / and then one or more spaces or lowercase ASCII letters
      • (?:/[go](?:/s)?)? - an optional occurrence of
        • /[go] - / and g or o
        • (?:/s)? - - an optional occurrence of /s
  • $ - end of string.
Related