我正在尝试从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')]
感谢您的咨询。
答案 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中的更改:现在可以在上一个空匹配之后立即开始非空匹配。
请注意粗体字。模式中有多个组:
正如文档所述,您会获得包含已捕获组的元组列表。
要只获取完整的mac地址,您需要在正则表达式中指定非捕获括号。 re模块文档说:
(?:...) 非捕获版本的常规括号。匹配括号内的任何正则表达式,但匹配子字符串 执行匹配后,无法检索到与组匹配的信息,或者 稍后在模式中引用。
因此,请修复所有非主括号(不能捕获整个mac地址)。