【问题标题】:Python regex findall() returning incorrect substrings [duplicate]Python正则表达式findall()返回不正确的子字符串[重复]
【发布时间】:2026-02-25 17:45:01
【问题描述】:

我正在尝试获取表单的所有子字符串的列表:

冒号+指定序列中2个字母的序列+最少1位的数值

import re
DATA_SUB = ':(TI|LO|TE|HU|AN|FO)[0-9\.]+'
print(re.findall(DATA_SUB, '%145:TI15:LO1.6213:TE97$'))

结果:

['TI', 'LO', 'TE']

它应该在哪里:

[':TI15', ':LO1.6213', ':TE97']

查看 re.findall() 文档:

返回字符串中所有不重叠的模式匹配,作为一个列表 字符串

可以得出结论,上述方法应该有效。我做错了什么?

【问题讨论】:

标签: python regex findall


【解决方案1】:

通过使用方括号您定义了一个捕获组,因此您要求 Python 返回捕获列表。通过将?: 放在组前面,您可以使其成为非捕获组

import re
DATA_SUB = ':(?:TI|LO|TE|HU|AN|FO)[0-9\.]+'
print(re.findall(DATA_SUB, '%145:TI15:LO1.6213:TE97$'))

例如,如果您要定义 两个 捕获组,您将生成一个包含两个组捕获的元组列表:

# educational counter example

import re
DATA_SUB = ':(TI|LO|TE|HU|AN|FO)([0-9\.]+)'
print(re.findall(DATA_SUB, '%145:TI15:LO1.6213:TE97$'))

将生成:

[('TI', '15'), ('LO', '1.6213'), ('TE', '97')]

【讨论】:

  • 一些无法解释的反对意见
  • @anubhava:如果我没记错的话,有一些(奇怪的)徽章/帽子,你可以通过多次投票来赢得......
  • 教育反例原来是我最终想要的!
  • @wit221:请注意,前导冒号 : 不匹配,因为它不属于任何捕获组。该示例的想法当然只是为了表明,如果您使用多个捕获组,每次捕获都会为您提供多个答案:)。
【解决方案2】:

在您的正则表达式中使用非捕获组而不是捕获组,以避免在findall 的输出中获取捕获的数据:

>>> DATA_SUB = ':(?:TI|LO|TE|HU|AN|FO)[0-9.]+'
>>> print re.findall(DATA_SUB, '%145:TI15:LO1.6213:TE97$')
[':TI15', ':LO1.6213', ':TE97']

【讨论】:

  • 为什么会被否决?
  • 我也想知道
  • 谢谢。您能否解释一下为什么可以删除点前面的转义字符,同时获得相同的预期结果?
  • 因为在字符类内部,即[...] 所有正则表达式元字符,例如., *, + 等按字面意思对待。
最近更新 更多