Reputation: 2065
I'm working on a JavaScript router engine for a client-side MVC app... something like Backbone or Spine is involved.
My router needs to match URI segments that optionally include resource titles and optionally include request formats.
I'm looking to capture the resource :id
, optional :name
segment and optional :format
segment, such that:
/123 => id:'123', name: undefined, format: undefined
/123-my-name => id:'123', name:'my-name', format: undefined
/123.html => id:'123', name: undefined, format:'html'
/123-my-name.html => id:'123', name:'my-name', format:'html'
EDIT: There are other routes that will match nested paths, so this expression should not match /123-my-name/edit
or /123-my-name/edit.html
I can easily match the optional :name
or :format
segments when they are not both present, but I'm having trouble distinguishing the :name
from the :format
when both are present.
Any suggestions?
Upvotes: 1
Views: 700
Reputation: 214959
> re = /\/(\w+)(?:-(\w[-\w]+))?(?:\.(html))?/
/\/(\w+)(?:-(\w[-\w]+))?(?:\.(html))?/
> "/123".match(re)
["/123", "123", undefined, undefined]
> "/123-my-name".match(re)
["/123-my-name", "123", "my-name", undefined]
> "/123.html".match(re)
["/123.html", "123", undefined, "html"]
> "/123-my-name.html".match(re)
["/123-my-name.html", "123", "my-name", "html"]
then,
m = url.match(re)
id = m[1]
name = m[2] || default
format = m[3] || default
A more specific option (id = only digits, anchored):
> re = /^\/(\d+)(?:-(\w[-\w]+))?(?:\.(html))?$/
/^\/(\d+)(?:-(\w[-\w]+))?(?:\.(html))?$/
> "/123-my-route/edit.html".match(re)
null
Upvotes: 3