【问题标题】:re.findall not returning correct results [duplicate]re.findall 没有返回正确的结果[重复]
【发布时间】:2017-05-16 14:37:33
【问题描述】:

我正在尝试从一些示例文本中返回 MAC 地址列表。 re.search 返回第一个结果,在这种情况下,我想要所有结果,但我只得到一个。当我使用re.findall 时,它会返回每个 MAC 地址的最后一个字符,而不是完整的地址。

有什么想法吗?

例如:

>>> test = """
...           Mac Address Table
... -------------------------------------------
...
... Vlan    Mac Address       Type        Ports
... ----    -----------       --------    -----
...   66    0800.0e54.9df0    STATIC      Gi2/0/27
...  100    5046.5a08.5a60    STATIC      Gi2/0/27
... Total Mac Addresses for this criterion: 2
... """
macs = re.search(r"([0-9A-Fa-f]){4}\.([0-9A-Fa-f]){4}\.([0-9A-Fa-f]){4}",test)
>>> print macs.group()
0800.0f54.99f0
macs = re.findall(r"([0-9A-Fa-f]){4}\.([0-9A-Fa-f]){4}\.([0-9A-Fa-f]){4}",test)
[('0', '4', '0'), ('6', '8', '0')]

【问题讨论】:

  • 删除所有捕获组。 macs = re.findall(r"[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}",test)
  • 谢谢!你想把它添加为答案以便我接受吗?

标签: python regex


【解决方案1】:

其他 awnsers 建议删除捕获组,但这不是您想要的,这不是解决问题的方法。

re.findall(pattern, string, flags=0)

返回字符串中所有不重叠的模式匹配,作为字符串列表。从左到右扫描字符串,并按找到的顺序返回匹配项。如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。空匹配包含在结果中,除非它们触及另一个匹配的开头。

真正的问题是在这里捕获组是错误的,我先过去了好的模式,然后是用于轻松检查差异的模式:

([0-9A-Fa-f]{4})\.([0-9A-Fa-f]{4})\.([0-9A-Fa-f]{4}) # good one
([0-9A-Fa-f]){4}\.([0-9A-Fa-f]){4}\.([0-9A-Fa-f]){4} # bad one

如您所见,如果您捕获由 4 个字符组成的所有字母数字字符串(([CHARS]{4}) 而不是 ([CHARS]){4},您将捕获一组中的所有字符串部分,因此 re.findall 将捕获字符组而不仅仅是字符一个接一个。

因为您是一个接一个地捕获字符并且 findall 返回 non-overlapping 匹配,所以您得到了这个结果。

模式良好的结果:

[('0800', '0e54', '9df0'), ('5046', '5a08', '5a60')]

【讨论】:

  • OP不需要包含十六进制字符块的元组列表,只需要MAC地址列表
【解决方案2】:

根据re.findall 文档:

如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。结果中包含空匹配项,除非它们触及另一个匹配项的开头。

因此,将所有正在捕获的组变成非捕获或尽可能将其删除(这里最好将它们删除,因为它们只是多余的):

macs = re.findall(r"[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}\.[0-9A-Fa-f]{4}"‌​,test)

【讨论】:

  • 这不是解决问题的好方法,因为它不回答问题也不解决问题,只是绕过它。
  • @Arount:看:我正在尝试返回 MAC 地址列表 - 这正是该解决方案所做的。
  • 你是对的,对不起,我的错。但是 python doc 的部分和您推荐的内容给人的印象是 re.findall 不支持错误的捕获组。我不能删除我的反对票,如果你编辑你的awser,我可以。
  • @Arount:首先,你错了。其次,我不在乎否决票,这是一个 Wiki 答案,您可以自己编辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2014-09-13
  • 2012-08-01
  • 2014-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多