我有一个看起来像这样的字符串
'\x00\x03\x10B\x00\x0e12102 G1103543\x10T\x07\x21'
我能够将我想要的数据“12102 G1103543”与此匹配。
re.findall('\x10\x42(.*)\x10\x54', data)
将输出此
'\x00\x0e12102 G1103543'
我遇到的问题是\ x10 \ x54并不总是在我想要的数据的末尾。然而,我注意到前两个十六进制数字对应于数据长度的长度。 I.E. \ x00 \ x0e = 14所以数据长度为14char。
有没有更好的方法来做到这一点,比如匹配第一部分然后削减接下来的14个字符?我还应该说,长度会因为我想要匹配几件事而变化。
还有一种方法可以输出所有十六进制中的字符串,这样我在python shell中工作时更容易阅读。 \ x10B == \ x10 \ x42
谢谢!
编辑:我设法提出了这个有效的解决方案。
newdata = re.findall('\x10\x42(.*)', data)
newdata[0][2:int(newdata[0][0:2].encode('hex'))]
答案 0 :(得分:0)
请注意,您手边有一个结构化的二进制文件,尝试使用正则表达式从中提取数据是愚蠢的。
首先,你谈到的“十六进制数据”不是“十六进制数据” - 它只是字节
在ASCII范围之外的流中 - 因此Python2会将这些字符显示为\x10
,依此类推 - 但在内部它只是一个值为16的单字节(当被视为十进制时)。您编写的\x42
对应于ASCII字母B
,这就是您在代表中看到B
的原因。
所以你最好的选择是获取文件规范,并使用struct
模块和字节串切片从那里读取你想要的数据。
如果您不能拥有文件规范,那么查找感兴趣的字段是一项逆向工程工作 - 就像您已经在做的那样。但即便如此,你应该用struct模块编写一些代码来获取你的值,因为字段长度(以及最有可能的偏移量)都是在字节流本身中编码的。
在此示例中,您的标记“\ x10 \ x42”很少会成为标记本身 - 很可能它的位置由文件中的其他因素指示(文件定义中的固定位置,或者早先在文件上偏移。
但是 - 如果您正确使用它作为标记,您可以使用正则表达式来查找“\ x10 \ x42”标记的所有偏移量,并将它们解释为以下两个字节消息长度:
import struct, re
def get_data(data, sep=b"\x10B"):
results = []
for match in re.finditer(sep, data):
offset = match.start()
msglen = struct.unpack(">H", data[offset + 2: offset + 4])[0]
print(msglen)
results.append(data[offset + 4: offset + 4 + msglen])
return results