re.findall没有返回正确的结果

时间:2017-01-02 13:19:55

标签: python regex

我正在尝试从一些示例文本中返回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')]

2 个答案:

答案 0 :(得分:1)

其他的扫描者建议删除捕获组,但这不是你想要的,这不是如何解决问题。

  

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

     

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

真正的问题是捕捉群体在这里是错误的,我首先通过良好的模式,然后用于轻松检查差异:

([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返回非重叠匹配,所以您获得了此结果。

结果良好的模式:

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

答案 1 :(得分:0)

根据re.findall文档:

  

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

因此,将所有捕获组转换为非捕获或删除它们(如果可能的话)(这里最好删除它们,因为它们只是多余的):

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