我想解析名为Docklight的串行监控程序的输出(我强烈推荐)
它输出'十六进制'字符串:或一系列(两个大写十六进制数字后跟一个空格)。相应的正则表达式为:([0-9A-F]{2} )+
,例如:'05 03 DA 4B 3F '
当程序检测到特定的字符序列时,它会将注释放在“十六进制”字符串中。例如:
'05 03 04 01 0A The Header 03 08 0B BD AF The PAYLOAD 0D 0A The Footer'
注释是以下格式的字符串' .+ '
(一个以空格开头并后跟空格的字符序列)
我想摆脱这些评论。例如,上面过滤的'十六进制'字符串将是:
'05 03 04 01 0A 03 08 0B BD AF 0D 0A '
我如何使用正则表达式执行此操作?
答案 0 :(得分:4)
您可以尝试re.findall()
:
>>> a='05 03 04 01 0A The Header 03 08 0B BD AF The PAYLOAD 0D 0A The Footer'
>>> re.findall(r"\b[0-9A-F]{2}\b", a)
['05', '03', '04', '01', '0A', '03', '08', '0B', 'BD', 'AF', '0D', '0A']
正则表达式中的\b
与“单词边界”匹配。
当然,如果串行监视器插入类似THIS BE THE HEADER
的内容,则输入不明确。
答案 1 :(得分:0)
假设插入的字符串不包含匹配项,可能更容易找到所有十六进制数字:
>>> data = '05 03 04 01 0A The Header 03 08 0B BD AF The PAYLOAD 0D 0A The Footer'
>>> import re
>>> pattern = re.compile("[0-9A-F]{2} ")
>>> "".join(pattern.findall(data))
'05 03 04 01 0A 03 08 0B BD AF AD 0D 0A '
否则你可以使用插入的字符串前面有两个空格的事实:
>>> data = '05 03 04 01 0A The Header 03 08 0B BD AF The PAYLOAD 0D 0A The Footer'
>>> re.sub("( .*?)(?=( [0-9A-F]{2} |$))","",data)
'05 03 04 01 0A 03 08 0B BD AF 0D 0A'
当插入的字符串结束时,这会使用前瞻性的方法。它查找由空格环绕的十六进制字符串或源字符串的末尾。
答案 2 :(得分:0)
使用你的正则表达式
hexa = '([0-9A-F]{2} )+'
" ".join(re.findall(hexa, line))
答案 3 :(得分:0)
虽然你已经收到了两个找到所有十六进制数字的答案,但这里的直接正则表达式会发现你看起来像十六进制数字的所有文本(假设两个字母/数字大写/小写0- 9和AF范围,然后是空格。
这样的事情(对不起,我不是pythoneer,但你明白了):
newstring = re.sub(r"[^ ]+(?<![0-9A-Fa-f ]{2}|^.)", "", yourstring)
它通过“回顾”工作。它找到每个连续的非空间子字符串,然后用(?<!....)
负面回顾。它说:“如果前两个字符不是十六进制数字,那么就成功”。最后的小^.
可以防止错误地匹配字符串的第一个字符。
正如艾伦·摩尔(Alan Moore)所建议的那样,这是一个积极的先行表达的相同想法:
newstring = re.sub(r"(?>\b[0-9A-Fa-f ]{2}\b)", "", yourstring)
答案 4 :(得分:0)
为何选择regexp?对我来说更pythonic是(固定为hexdigit而不是常规数字):
command='05 03 04 01 0A The Header 03 08 0B BD AF The PAYLOAD 0D 0A The Footer'
print ' '.join(com for com in command.split()
if len(com)==2 and all(c.upper() in '0123456789ABCDEF' for c in com))
答案 5 :(得分:0)
实际使用正则表达式否定的解决方案怎么样? ;)
result = re.sub(r"[ ]+(?:(?!\b[0-9A-F]{2}\b).)+", "", subject)