正则表达式:如何访问多个匹配的组?

108 投票
2 回答
134356 浏览
提问于 2025-04-16 12:11

我正在编写一个比较复杂的正则表达式。其中一部分是用来匹配像 '+a'、'-57' 这样的字符串,也就是一个 '+' 或 '-' 后面跟着任意数量的字母或数字。我想要匹配0个或多个符合这个模式的字符串。

这是我想出来的表达式:

([\+-][a-zA-Z0-9]+)*

如果我用这个模式去搜索字符串 '-56+a',我希望能找到两个匹配项:

+a 和 -56

但是,我只得到了最后一个匹配项:

>>> m = re.match("([\+-][a-zA-Z0-9]+)*", '-56+a')
>>> m.groups()
('+a',)

查看 Python 的文档,我发现:

如果一个组匹配了多次,只有最后一个匹配项是可以访问的:

>>> m = re.match(r"(..)+", "a1b2c3")  # Matches 3 times.
>>> m.group(1)                        # Returns only the last match.
'c3'

所以,我的问题是:如何才能访问多个匹配的组呢?

2 个回答

53

regex模块解决了这个问题,它增加了一个叫做.captures的方法:

>>> m = regex.match(r"(..)+", "a1b2c3")
>>> m.captures(1)
['a1', 'b2', 'c3']
87

把你的正则表达式中的*去掉,这样它就只会匹配一次你想要的模式。然后可以使用re.findall(...)或者re.finditer(详细信息可以查看这里)来获取所有的匹配结果。

听起来你其实是在构建一个递归下降解析器。对于相对简单的解析任务,手动实现是很常见也很合理的。如果你对使用库的解决方案感兴趣(比如将来你的解析任务可能会变得更复杂),可以看看pyparsing

撰写回答