Jarrod Carlson
Jarrod Carlson

Reputation: 2065

Regular expression to match uri segment in javascript

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

Answers (1)

georg
georg

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

Related Questions