Python Regex从最后匹配一个mac地址?

时间:2015-09-24 05:42:35

标签: python regex

我有以下重新提取MAC地址:

re.sub( r'(\S{2,2})(?!$)\s*', r'\1:', '0x0000000000aa bb ccdd ee ff' )

然而,这给了我0x:00:00:00:00:00:aa:bb:cc:dd:ee:ff

如何在从最后开始匹配前6对之后修改此正则表达式,以便我得到aa:bb:cc:dd:ee:ff

注意:字符串之间有空格,可以忽略。只需要最后12个字符。

Edit1: re.findall( r'(\S{2})\s*(\S{2})\s*(\S{2})\s*(\S{2})\s*(\S{2})\s*(\S{2})\s*$',a)查找字符串中的最后6对。我仍然不知道如何压缩这个正则表达式。同样,这仍然取决于字符串成对的事实。

理想情况下,正则表达式应从最后开始使用最后12个有效\S个字符,并将其与:

字符串联系起来

编辑2:受到@Mariano答案的启发很有效,但取决于最后12个字符必须从一对开始的事实我想出了以下解决方案。它很笨,但似乎仍适用于所有输入。

string = '0x0000000000a abb ccddeeff'
':'.join( ''.join( i ) for i in re.findall( '(\S)\s*(\S)(?!(?:\s*\S\s*{11})',' string) )
'aa:bb:cc:dd:ee:ff'

编辑3: @Mariano更新了现在适用于所有输入的答案

4 个答案:

答案 0 :(得分:2)

这将适用于最后12个字符,忽略空格。

<强>代码:

import re

text = "0x0000000000aa bb ccdd ee ff"

result = re.sub( r'.*?(?!(?:\s*\S){13})(\S)\s*(\S)', r':\1\2', text)[1:]

print(result)

<强>输出:

aa:bb:cc:dd:ee:ff

DEMO

正则表达式细分:

此代码中使用的表达式使用re.sub()替换主题文本中的以下内容:

.*?                 # consume the subject text as few as possible
(?!(?:\s*\S){13})   # CONDITION: Can't be followed by 13 chars
                    #  so it can only start matching when there are 12 to $
(\S)\s*(\S)         # Capture a char in group 1, next char in group 2
                    #
  # The match is replaced with :\1\2
  # For this example, re.sub() returns ":aa:bb:cc:dd:ee:ff"
  # We'll then apply [1:] to the returned value to discard the leading ":"

答案 1 :(得分:1)

您可以使用re.finditer查找所有对,然后加入结果:

>>> my_string='0x0000000000aa bb ccdd ee ff'
>>> ':'.join([i.group() for i in re.finditer( r'([a-z])\1+',my_string )])
'aa:bb:cc:dd:ee:ff'

答案 2 :(得分:0)

你可以这样做,

>>> import re
>>> s = '0x0000000000aa bb ccdd ee ff'
>>> re.sub(r'(?!^)\s*(?=(?:\s*[a-z]{2})+$)', ':', re.sub(r'.*?((?:\s*[a-z]){12})\s*$', r'\1', s ))
'aa:bb:cc:dd:ee:ff'
>>> s = '???767aa bb ccdd ee ff'
>>> re.sub(r'(?!^)\s*(?=(?:\s*[a-z]{2})+$)', ':', re.sub(r'.*?((?:\s*[a-z]){12})\s*$', r'\1', s ))
'aa:bb:cc:dd:ee:ff'
>>> s = '???767aa bb ccdd eeff    '
>>> re.sub(r'(?!^)\s*(?=(?:\s*[a-z]{2})+$)', ':', re.sub(r'.*?((?:\s*[a-z]){12})\s*$', r'\1', s ))
'aa:bb:cc:dd:ee:ff'

答案 3 :(得分:0)

我知道这不是你问题的直接答案,但你真的需要一个正则表达式吗?如果你的格式是固定的,这也应该有效:

>>> s = '0x0000000000aa bb ccdd ee ff'
>>> ':'.join([s[-16:-8].replace(' ', ':'), s[-8:].replace(' ', ':')])
'aa:bb:cc:dd:ee:ff'