我的任务是使用Python 3编写程序。我是Python的新手。
我需要从.bin文件中获取十六进制数据,然后每次看到特定十六进制模式的出现时对数据进行分区(例如:每个块从01 03开始)。最后,我需要输出每个块的分区数和大小(以字节为单位)。
到目前为止,我已经从.bin文件中读取数据,并使用re.findall对每个数据块进行分区。我的正则表达式看起来像这样:
B “\ X01 \ X03(?(?!\ X01 \ X03)。)*”
re.findall运行良好,但我现在有一个大约300个十六进制块的列表(因为我使用了re.findall),我现在不知道如何检查每个块的大小(以字节为单位)。有人可以帮我弄这个吗?
你可以使用enumerate
:
regex = b'\x01\x03(?(?!\x01\x03).)*'
chunk_lengths = {index: len(chunk) for index, chunk in enumerate(re.findall(regex, data))}
您最初使用re.findall
来获取源数据中的每个块,这些块遵循您给定的正则表达式。这些是bytes
对象,它们具有明确定义的长度(其中的字节数)。
使用len
运算符,我们可以找到每个块的长度,这些将形成我们字典的值。如果我们做了[len(chunk) for chunk in re.findall(regex, data))]
,那将按照发现的顺序给我们列出所有发现的块的长度(这在以后很重要)。
enumerate
是一个内置函数,允许“标记”索引(默认情况下从0开始)到某个可迭代对象。所以,假设你有一个list
[5, 3, 4]
,代表块长度。如果你对它应用enumerate
,你会得到tuple
s (0, 5)
(索引0,长度5),(1, 3)
(索引1,长度3)和(2, 4)
(索引2,长度4)。
现在,通过将所有内容放在dict
理解中,我们变得更能够通过enumerate
创建的索引访问块的长度。因为,如上所述,findall
按顺序返回结果列表,枚举也按顺序运行,enumerate
创建的索引也是块在原始数据中的相对位置。
我建议
l = re.compile("\x01\x03(?(?!\x01\x03).)*").split(s)
len(l) - 1
测试结果:
>>> re.compile(r"\x01\x03").split(b"\x01\x03\0x4\0x5\x01\x03\0x6\0x7")
['', '\x00x4\x00x5', '\x00x6\x00x7']
当然你应该确保正则表达式是正确的。