正则表达式(Python) - 匹配MAC地址

时间:2016-08-09 18:45:55

标签: python regex mac-address regular-language

我有这个文本(来自ipconfig / all)

Ethernet adapter Local Area Connection:

   Connection-specific DNS Suffix  . :    
   Description . . . . . . . . . . . : Atheros AR8151 PCI-E Gigabit Ethernet    Controller (NDIS 6.20)   
   Physical Address. . . . . . . . . : 50-E5-49-CE-FC-EF   
   DHCP Enabled. . . . . . . . . . . : Yes   
   Autoconfiguration Enabled . . . . : Yes    
   Link-local IPv6 Address . . . . . : fe80::5cba:e9f2:a99f:4499%11(Preferred)    
   IPv4 Address. . . . . . . . . . . : 10.0.0.1(Preferred)    
   Subnet Mask . . . . . . . . . . . : 255.255.255.0   
   Lease Obtained. . . . . . . . . . : ™ 06 €…‚…‘ˆ 2016 20:35:49   
   Lease Expires . . . . . . . . . . : ‰…™‰™‰ 09 €…‚…‘ˆ 2016 21:05:49   
   Default Gateway . . . . . . . . . : 10.0.0.138   
   DHCP Server . . . . . . . . . . . : 10.0.0.138   
   DHCPv6 IAID . . . . . . . . . . . : 240182601   
   DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-19-7A-1F-FC-50-E5-49-CE-FC-EF   
   DNS Servers . . . . . . . . . . . : 10.0.0.138   
   NetBIOS over Tcpip. . . . . . . . : Enabled    

Ethernet adapter Local Area Connection* 11:   

   Description . . . . . . . . . . . : Juniper Networks Virtual Adapter    
   Physical Address. . . . . . . . . : 02-05-85-7F-EB-80     
   DHCP Enabled. . . . . . . . . . . : No    
   Autoconfiguration Enabled . . . . : Yes    
   Link-local IPv6 Address . . . . . : fe80::8dfb:6d42:97e1:2dc7%19(Preferred)     
   IPv4 Address. . . . . . . . . . . : 172.16.2.7(Preferred)      
   Subnet Mask . . . . . . . . . . . : 255.255.255.255     
   Default Gateway . . . . . . . . . :       
   DHCPv6 IAID . . . . . . . . . . . : 436340101     
   DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-19-7A-1F-FC-50-E5-49-CE-FC-EF    
   DNS Servers . . . . . . . . . . . : 172.16.0.6     
                                       172.16.0.91     
   NetBIOS over Tcpip. . . . . . . . : Enabled     

我想只选择物理地址(MAC)

从这里开始它将是2:
50-E5-49-CE-FC-EF 02-05-85-7F-EB-80

此(link([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})无效,因为
这也将是 00-01-00-01-19-7A-1F-FC-50-E5-49-CE-FC-EF
所以我已将其修复为([^-])([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})([^-])  (在开始和结束时不强制-
但是现在我开始在脑袋里进入空白,最后得到/n 这是链接:https://regex101.com/r/kJ7mC0/1

我需要优雅 正则表达式来解决它。

1 个答案:

答案 0 :(得分:1)

您在两边都获得了非-符号,因为否定的字符类[^-]匹配并使用了字符。为避免在匹配值中获取这些字符,您可以使用lookarounds:

p = re.compile(r'(?<!-)(?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2}(?!-)', re.IGNORECASE)
                 ^^^^^^                                  ^^^^

(?<!-)负面后瞻确保在您需要提取的值之前没有-(?!-)是一个负面预测,如果有{{1在此值之后。

如果不期望-分隔符,请将:替换为[:-]。与-一起使用。

此外,所有re.findall都应转为(...)非捕获组,以免“破坏”匹配结果。

请参阅Python demo

替代方案可以是正则表达式,其中1个捕获组捕获我们需要的内容,并匹配我们不需要的内容:

(?:...)

它看起来不那么优雅,但其工作方式与p = re.compile(r'(?:^|[^-])((?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2})(?:$|[^-])', re.IGNORECASE) 非捕获组不包含在(?:^|[^-])结果中的方式相同,并且匹配字符串的开头或除了字符串以外的符号re.findall-匹配字符串的结尾或(?:$|[^-])以外的符号。

此外,要缩短模式,您可以在字符类中仅使用-替换a-fA-F,并使用a-fre.IGNORECASE标记。