views:

203

answers:

3

Currently I have three URL paths that map to ServiceHandler. How do I combine the three into one neat regex that can pass n number of arguments to ServiceHandler?

(r'/s/([^/]*)', ServiceHandler),
(r'/s/([^/]*)/([^/]*)', ServiceHandler),
(r'/s/([^/]*)/([^/]*)/([^/]*)', ServiceHandler)
A: 

You can try something like

(r'/s/([^/]*)/?([^/]*)/?([^/]*)', ServiceHandler)

I think you will always get 3 parameters to ServiceHandler but the ones that aren't used will be empty strings

gnibbler
what about passing 5 or 10? Isn't there a way to write an expression that will handle any number of params?
+1  A: 
(r'^/s/(([^/]*)((/[^/]+)*))$', ServiceHandler)

Should do the trick to match any amount of

/s/foo/bar/baz/to/infinity/and/beyond/

You can also limit it to a range by doing something like

^/s/(([^/]*)((/[^/]+){0,2}))$

Which would only match things like

/s/foo/bar/baz
/s/foo/bar
/s/foo

but not

/s/foo/bar/baz/pirate
/s
Mez
Thanks. (r'^/s/(([^/]*)((/[^/]+)*))$', ServiceHandler) with http://localhost:8080/s/1/2/3/4 gives me these arguments ('1/2/3/4', '1', '/2/3/4', '/4'). Not sure how to modify it to give ('1','2','3','4').
*chuckles* I've no idea myself, as a recursive patter will always give the last match....
Mez
A: 

This should work for any number

(r'(?<!^)/([^/]+)', ServiceHandler)

Since I've looked in urlresolvers.py, I see this won't work although you could patch the correct behaviour into urlresolvers.py using regex.findall instead of re.search.

gnibbler
nope doesn't match any of /s/foo/bar/baz/s/foo/bar/s/foo
The problem is in urlresolvers.py they are using re.search. If they had used re.findall it would have worked. re.search only returns the first successful match, that means you are stuck with a fixed number of groups
gnibbler