Python中使用re.findall匹配字节对象特定开头序列的问题
解决二进制文件中匹配特定序列并获取偏移量的问题
我帮你排查下代码里的问题,顺便给出能实现需求的方案:
首先说你代码里的几个核心问题:
- 没必要用
binascii.b2a_hex把二进制转成十六进制字节串,直接操作原始二进制数据更简单,而且偏移量计算会和你用GUI编辑器看到的完全一致 - 正则表达式写错了:二进制模式下
b'\x([A-Z])'是无效语法,你要匹配的是0x24(也就是ASCII的$)开头,后面跟3-10个任意字节的话,正则应该写成b'\x24.{3,10}';如果后面的字节有特定范围要求(比如只匹配ASCII大写字母),再把.{3,10}改成[A-Z]{3,10} - 循环
list(data)完全是多余的,re.findall直接作用在二进制数据上就行,而且你要获取偏移量的话,findall满足不了,得用re.finditer - 关于用
groupdict:那是针对带命名分组的正则,你这个需求不需要,用finditer返回的匹配对象就能直接拿到偏移和内容
下面是修正后的完整代码:
import re import binascii # 如果需要转十六进制字符串的话用 infile = "my_file.bin" # 替换成你的文件路径 # 存储匹配到的序列(可以是二进制或十六进制字符串) match_list = [] # 存储偏移量与对应序列的字典,键是偏移量,值是序列 match_offset_dict = {} with open(infile, "rb") as f: raw_data = f.read() # 编译正则:匹配0x24开头,后续3-10个任意字节的序列 # 若要限定后续字节范围,比如只匹配ASCII大写字母,改成 b'\x24[A-Z]{3,10}' pattern = re.compile(b'\x24.{3,10}') # 遍历所有匹配结果 for match in pattern.finditer(raw_data): # 获取原始二进制序列 binary_seq = match.group() # 获取序列在文件中的起始字节偏移 start_offset = match.start() # 如果你需要和GUI编辑器里一样的十六进制字符串格式,就转一下 hex_seq = binascii.hexlify(binary_seq).upper().decode('ascii') # 添加到列表(选二进制或十六进制版本,根据你的需求) match_list.append(hex_seq) # 或者 append(binary_seq) # 添加到字典 match_offset_dict[start_offset] = hex_seq # 或者 binary_seq # 验证结果 print("匹配到的序列列表:", match_list) print("偏移量-序列字典:", match_offset_dict)
几个关键说明:
- 直接读取二进制文件的原始数据,这样
match.start()返回的偏移量就是你在GUI十六进制编辑器里看到的字节偏移,完全对应 re.finditer返回的每个Match对象,不仅能拿到匹配的内容,还能获取起始/结束偏移,完美满足你要同时存序列和偏移的需求- 如果需要把二进制序列转成十六进制字符串(比如像GUI里显示的
24414243这样的格式),就用binascii.hexlify转换,再转成大写和字符串格式就行
内容的提问来源于stack exchange,提问作者therealjayvi
相关产品推荐
相关产品推荐

