python3 arp-scan和mac解析

时间:2018-11-22 13:56:33

标签: python python-3.x mac-address arp

我正在尝试从arp-scan输出中解析mac地址。 有一个例子:

import re
from subprocess import Popen, PIPE

def get_active_hosts():
    with Popen(['sudo', 'arp-scan', '-l', '-r', '5'], stdout = PIPE) as proc:
        mac_list = re.compile('\s+(([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]){2})\s+')
        mac_list = mac_list.findall(proc.stdout.read().decode('utf-8'))
    return mac_list
print(get_active_hosts())

但是我得到了以下输出:

[('4a:c3:26:0e:85:d0', '85:', '0')]

这是怎么回事?如何仅捕获没有此垃圾的mac地址:

[(''85:','0')]

感谢您的咨询。

2 个答案:

答案 0 :(得分:0)

findall返回所找到的所有匹配组。组使用一组括号声明。您的正则表达式包含三组,如下所示:

(([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]){2})
([0-9A-Fa-f]{2}:)
([0-9A-Fa-f])

所以现在希望您能理解为什么findall给您三场比赛,以及为什么看起来像他们一样。

这里的解决方案是通过在开括号后面放置?:来声明这些额外的组(您不想要的组)不捕获

mac_list = re.compile('\s+((?:[0-9A-Fa-f]{2}:){5}(?:[0-9A-Fa-f]){2})\s+')

答案 1 :(得分:0)

让我们看一下findall方法的文档:

  

re.findall(模式,字符串,标志= 0)

     

以字符串列表形式返回字符串中所有不重复的模式匹配项。字符串从左到右扫描,并且匹配项是   以找到的顺序返回。 如果一个或多个组存在于   模式,返回组列表;这将是一个元组列表,如果   模式包含多个组。空匹配项包含在   结果。

     

版本3.7中的更改:现在可以在上一个空匹配之后立即开始非空匹配。

请注意粗体字。模式中有多个组:

  • (([[0-9A-Fa-f] {2}:){5}([0-9A-Fa-f])=>'4a:c3:26:0e:85:d0' li>
  • ([[0-9A-Fa-f] {2} :) => '85:'
  • ([0-9A-Fa-f])=>'0'

正如文档所述,您会获得包含已捕获组的元组列表。

要只获取完整的mac地址,您需要在正则表达式中指定非捕获括号。 re模块文档说:

  

(?:...)   非捕获版本的常规括号。匹配括号内的任何正则表达式,但匹配子字符串   执行匹配后,无法检索到与组匹配的信息,或者   稍后在模式中引用。

因此,请修复所有非主括号(不能捕获整个mac地址)。