Skip to main content
 首页 » 编程设计

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

2025年05月04日32Terrylee

是否可以构造一个正则表达式来捕获由一系列字符分隔的文本的所有出现?换句话说,我正在寻找与标准 .split() 方法等效的方法。

我不能使用 split(),因为正则表达式用于指定 Tornado 网络应用程序的 URL 路由。例如:

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

当为基于 Tornado、Django 或任何其他实现路由模式的 Web 框架构建的 Web 应用程序指定 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']

请您参考如下方法:

在 Python 中无法匹配无限数量的捕获。每个捕获组只能捕获一个匹配项,根据 Python 中的定义,它会捕获最后一个匹配项。具体请参见 MatchObject.group 上的文档:

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

具体来说,下面的文字解释了捕获组的局限性:

If a group is contained in a part of the pattern that matched multiple times, the last match is returned.

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

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

您可能会按照前面的模板动态构造正则表达式的字符串,但无论哪种方式,都会非常糟糕。