Regex for capturing all occurrences of text delimited by a sequence of characters
Is it possible to construct a regular expression that captures all occurrences of text delimited by a sequence of characters? In other words, I am looking for an equivalent of standard .split()
method.
I can't use split()
, because the regular expression is used in specifying URL routes for Tornado web application. For example:
handlers = [
(r'/posts/([0-9a-zA-Z_\-]+)', PostsHandler),
]
Such a regular expression comes in handy when specifying URL routes for web applications built on top of Tornado, Django or any other web framework which implements Routes pattern. In particular, to parse a URL path of unknown length into a list of arguments.
So far I have managed to come up with the following regular expression:
/^\/posts(?:\/([a-zA-Z0-9_\-]+))+/
Unfortunately, while the expression matches /posts/show/some-slug/15
, it only returns the last matching group (15
), instead of ['show', 'some-slug', '15']
.
What I want is achieve is:
/posts/edit/15/
=>['edit', '15']
/posts/edit/15
=>['e开发者_开发问答dit', '15']
/posts/2010/15/11
=>['2010', '15', '11']
There is no way to match an unbounded number of captures in Python. Each capture group can only capture a single match, and by definition in Python it captures the last match. Specifically, see the documentation on MatchObject.group:
http://docs.python.org/library/re.html#re.MatchObject.group
Specifically, the following text explains the limitation of capture groups:
If a group is contained in a part of the pattern that matched multiple times, the last match is returned.
Thus the only way to capture multiple matches is to make an upper bound on the total number of capture groups. So something like the following (untested) would match up to five captures:
/^\/posts\/([\w-]+)(?:\/([\w-]+)(?:\/([\w-]+)(?:\/([\w-]+)(?:\/([\w-])+)?)?)?)?
You could potentially construct the string for the regular expression dynamically following the previous template, but either way, it's going to be pretty horrible.
Have you tried: str.split('/')
? This should do exactly what you want (if I understand correctly). Is there any reason why it must be a regular expression?
To catch all the occurences matched by a regex, you use
[ match.groups(....) for match in pattern.finditer(the_string) ]
To split according a pattern, you use:
re.split()
very interesting function
I don't know Python regex, but what you want is a global match. If you add a g
to the end of your regex it should do the trick in the languages I'm familiar with.
/^\/posts(?:\/([a-zA-Z0-9_\-]+))+/g
Also, many languages have a regex-based split
function. Consider that if it's available, or just the good old string split function (which really seems more like the tool you want here).
精彩评论