1

I need a regex that should match the following strings:

  • users/24
  • users/24/
  • users/24/sam
  • users/24/sam/
  • users/24/sam/tab_name
  • users/24/sam/tab_name/

where, pk=24, username=sam, tab=tab_name

So far I have a url as:

url(r'^users/(?P<pk>\d+)/(?P<username>[-\w\d]+)?/?(?P<tab>[-\w\d]+)?/?', vw.ProfileView.as_view(), name='profile')

The above url matches everything above. But while using

{% url 'profile' pk=24 username="sam" tab="tab_name" %}

the output is : users/samtab_name

I know the problem here i.e, /? optional slash. But I don't want it to be optional when using {% url 'profile' pk=24 username="sam" tab="tab_name" %}

Help me with this.

whitehat
  • 2,644
  • 1
  • 12
  • 35
  • 1
    Try [`^users/(?P\d+)(?:/(?P[-\w]+))?(?:/(?P[-\w]+))?/?`](https://regex101.com/r/TIKklT/1). Not sure you need the last `/?` though. – Wiktor Stribiżew Aug 08 '18 at 12:52
  • I suggest you make the slash required (use `/` instead of `/?`). Then the default Django behaviour will be to redirect to the URLs with the slash (e.g. `/users/24/sam` -> `/users/24/sam/`). See the docs on [`append_slash`](https://docs.djangoproject.com/en/2.1/ref/settings/#append-slash) for more info. – Alasdair Aug 08 '18 at 13:00
  • @WiktorStribiżew Your regex did the work though. I would appreciate if you explained `?:` – whitehat Aug 08 '18 at 13:13

1 Answers1

2

You may make your / obligatory by placing them together with the named capturing groups inside optional non-capturing groups:

^users/(?P<pk>\d+)(?:/(?P<username>[-\w]+))?(?:/(?P<tab>[-\w]+))?/?

See the regex demo.

Note that \w already matches digits, so you do not need \d inside the character classes.

Details

  • ^ - start of string
  • users/ - a literal substring
  • (?P<pk>\d+) - a named capturing group "pk" matching 1+ digtis
  • (?:/(?P<username>[-\w]+))? - an optional non-capturing group (there is ? quantifier after the closing )) matching
    • / - a / char
    • (?P<username>[-\w]+) - Group "username": 1+ word or - chars
  • (?:/(?P<tab>[-\w]+))? - an optional non-capturing group matching
    • / - a / char
    • (?P<tab>[-\w]+) - Group "tab": 1+ word or - chars
  • /? - an optional / char.
Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397