正则表达式:如何访问一个组的多个匹配项? [复制]

Posted

技术标签:

【中文标题】正则表达式:如何访问一个组的多个匹配项? [复制]【英文标题】:regexes: How to access multiple matches of a group? [duplicate] 【发布时间】:2011-06-30 22:42:49 【问题描述】:

我正在组合一个相当复杂的正则表达式。表达式的一部分匹配诸如“+a”、“-57”等字符串。A + 或a - 后跟任意数量的字母或数字。我想匹配 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'

所以,我的问题是:如何您访问多个小组比赛?

【问题讨论】:

【参考方案1】:

regex module 通过添加 .captures 方法解决了这个问题:

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

【讨论】:

这个答案比目前接受的答案更简单地解决了我的问题。 regex 模块也应该在未来取代 Python re 模块。 这是什么黑魔法!【参考方案2】:

从您的正则表达式中删除*(这样它就与您的模式的一个实例完全匹配)。然后使用re.findall(...)re.finditer(参见here)返回所有匹配项。

更新:

听起来您实际上是在构建recursive descent parser。对于相对简单的解析任务,手动完成是很常见且完全合理的。如果您对库解决方案感兴趣(例如,如果您的解析任务稍后可能变得更加复杂),请查看pyparsing。

【讨论】:

感谢您的回复。问题是我的问题中的表达只是更长表达的一部分。我正在尝试标记用户输入的字符串。我想我可能不得不采取“分而治之”的方法,断开将包含由表达式的这一部分标识的组的字符串部分,然后按照您的建议应用 re.findall 。再次感谢您的帮助! 可能值得注意的是 re.findall(pattern, string) 会在字符串中找到所有出现的模式,即使这些出现是不连续的。即: re.findall('a.', 'axayaz') == re.findall('a.', '--ax---ay-----az--------') == ['ax', 'ay', 'az'] 是的,不幸的是,在我的情况下,字符串中的位置是相关的。字符串的一部分中的“+a”在另一部分可能意味着完全不同的东西。谢谢。 @Tom:我在答案中添加了一些更高级的链接。如果这回答了您的问题,请投票(绿色复选标记/向上箭头)以将此问题标记为已解决。 感谢这些链接 phooji - 非常有趣。我已将您的答案标记为已接受。谢谢大家!

以上是关于正则表达式:如何访问一个组的多个匹配项? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式查找具有特定起始字符串的所有匹配项? [复制]

如何从 Typescript 中的正则表达式 exec 匹配访问组? [复制]

具有多个捕获组的 R 中的正则表达式组捕获

在 PySpark 中提取多个正则表达式匹配项

正则表达式获取 C# 中模式的所有可能匹配项

使用正则表达式查找两个字符串之间的多个匹配项