用于捕获由字符序列分隔的所有文本出现的正则表达式

1 投票
4 回答
2077 浏览
提问于 2025-04-16 13:11

有没有办法写一个正则表达式,能够抓取被一串字符分隔的所有出现的文本?换句话说,我想找一个和标准的 .split() 方法一样的东西。

我不能使用 split(),因为这个正则表达式是用来指定Tornado网页应用的URL路由的。例如:

handlers = [
    (r'/posts/([0-9a-zA-Z_\-]+)', PostsHandler),
]

这样的正则表达式在为基于Tornado、Django或其他实现了路由模式的网页框架指定URL路由时非常有用。特别是,它可以把长度不确定的URL路径解析成一个参数列表。

到目前为止,我想出了以下的正则表达式:

/^\/posts(?:\/([a-zA-Z0-9_\-]+))+/

不幸的是,虽然这个表达式可以匹配 /posts/show/some-slug/15,但它只返回最后一个匹配的部分(15),而不是 ['show', 'some-slug', '15']

我想要实现的是:

  • /posts/edit/15/ => ['edit', '15']
  • /posts/edit/15 => ['edit', '15']
  • /posts/2010/15/11 => ['2010', '15', '11']

4 个回答

1

你试过用 str.split('/') 吗?这个方法应该正好能满足你的需求(如果我理解得没错的话)。有没有什么特别的原因需要用正则表达式呢?

1

要捕捉正则表达式匹配到的所有内容,你可以使用:

[ match.groups(....) for match in  pattern.finditer(the_string) ]

要根据某个模式进行分割,你可以使用:

re.split()

这个函数非常有意思

6

在Python中,无法匹配无限数量的捕获。每个捕获组只能捕获一个匹配项,而且根据Python的定义,它只会捕获最后一个匹配的结果。具体来说,可以查看关于MatchObject.group的文档:

http://docs.python.org/library/re.html#re.MatchObject.group

下面的文字解释了捕获组的限制:

如果一个组位于模式的某个部分,并且该部分匹配了多次,那么返回的将是最后一次匹配的结果。

因此,捕获多个匹配项的唯一方法是对捕获组的总数设定一个上限。比如下面这个(未经测试)可以匹配最多五个捕获:

/^\/posts\/([\w-]+)(?:\/([\w-]+)(?:\/([\w-]+)(?:\/([\w-]+)(?:\/([\w-])+)?)?)?)?

你可以根据之前的模板动态构建正则表达式的字符串,但无论如何,这都会相当麻烦。

撰写回答