如何捕获二进制字符串中的所有字符而无需python进行解释

如何捕获二进制字符串中的所有字符而无需python进行解释,python,regex,struct,Python,Regex,Struct,下面是我如何重现这个问题的: 创建一个名为“temp.log”的日志文件,并将此行粘贴到其中 DEBUG: packetReceived '\x61\x62\x63' 调试:收到的数据包“\x61\x62\x63” 我想要一个脚本,它将读取日志文件中的行并解码二进制字符串部分('\x61\x62\x63')。对于解码,我使用struct,因此: struct.unpack('BBB', '\x61\x62\x63') 解包结构('BBB','\x61\x62\x63') 应该给我 (97, 98

下面是我如何重现这个问题的:

创建一个名为“temp.log”的日志文件,并将此行粘贴到其中

DEBUG: packetReceived '\x61\x62\x63' 调试:收到的数据包“\x61\x62\x63” 我想要一个脚本,它将读取日志文件中的行并解码二进制字符串部分('\x61\x62\x63')。对于解码,我使用struct,因此:

struct.unpack('BBB', '\x61\x62\x63') 解包结构('BBB','\x61\x62\x63') 应该给我

(97, 98, 99) (97, 98, 99) 这是我正在使用的脚本

import re import struct import sys f = open(sys.argv[1], 'r') for line in f: print line packet = re.compile(r"packetReceived \'(.*)\'").search(line).group(1) # packet is the string r'\x61\x62\x63' assert(len(packet), 12) # this works ok (returns (97, 98, 99)) struct.unpack('BBB', '\x61\x62\x63') # this fails because packet is interpreted as r'\\x61\\x62\x63' struct.unpack('BBB', packet) 进口稀土 导入结构 导入系统 f=打开(sys.argv[1],'r') 对于f中的行: 打印行 packet=re.compile(r“packetReceived\”(.*)\”).search(行).group(1) #数据包是字符串r'\x61\x62\x63' 断言(len(数据包),12) #这工作正常(返回(97、98、99)) 解包结构('BBB','\x61\x62\x63') #此操作失败,因为数据包被解释为r'\\x61\\x62\x63' 解包结构('BBB',数据包) 我使用temp.log作为脚本的参数运行脚本

希望这些评论能突出我的问题。如何将变量数据包解释为“\x61\x62\x63”

旁白:在这个问题的第一次编辑中,我假设从文件中读取的行与此相同: line=“DEBUG:packetReceived'\x61\x62\x63'” 这使得数据包=='abc'

但是,它实际上与此相同(使用rawstring)
line=r“DEBUG:packetReceived'\x61\x62\x63'

如果您确定接收到的是12个字符,而不仅仅是3个字符表示为12个,那么可能是打印字符串引起了您的悲伤

比较:

>> print '\x61\x62\x63'
abc
>>> print r'\x61\x62\x63'
\x61\x62\x63
我的50c在你身上,实际上收到了三个字符,它们被打印成这样:

>>> print ''.join('\\x%02x' % ord(c) for c in 'abc')
\x61\x62\x63

不,这一行不是问题所在。

Python不会解释传递给正则表达式的字符串。当您定义变量
line
时,最有可能在前面解释转义序列。这是正确的,例如:

line = r"DEBUG: packetReceived '\x61\x62\x63'"
print re.compile(r"packetReceived '(.*)'").search(line).group(1)

它打印
\x61\x62\x63

如您的问题所述,数据包等于
'\x61\x62\x63'
。它的len是12字节,既不是15字节也不是3字节

让您困惑的是,ipython(我知道您正在使用它)和python解释器使用
repr()
调用来显示值,该调用试图按照代码中的格式设置值。由于反斜杠在Python字符串常量中是特殊的,
repr()
显示重复的反斜杠,就像在Python代码中一样

这可能会有所帮助:

for char in packet:
    print("%5d %2s %2r" % (ord(char), char, char))
数一数你的字符,看看它们是如何打印出来的。第一列显示字符的序号值,第二列显示字符本身,第三列显示字符的
repr

编辑 更改最后一行:

struct.unpack('BBB', packet)
致:


你确定你收到的是12个字符,而不仅仅是3个代表12个字符吗?@johnsyweb有12个字符。我附加的调试语句实际上是文本文件的一个副本/粘贴。你嗅到了在电线上发送的是什么吗?@johnsyweb:我没有尝试剪切数据包,因为我在这里真正尝试的是从日志文件中获取数据包的字符串表示并解码它。当我从日志文件复制/粘贴字符串时,解码工作正常。我真正的问题是将字符串表示读入一个变量并在解码器中使用它。在从反馈中得到一些有用的提示后,我更新了这个问题。好的,我现在看得更好了(我想)。所以问题实际上是当我执行代码的“for line in f”部分时。我需要一些方法使行不解释转义序列。@ephesian:文件读取通常也不应该解释转义序列。你不会来调试你的代码(并通过
print
stations)来找出具体发生在哪里,因为我猜不到。谢谢。你说得很对。我意识到,我试图通过手动设置行(而不是使用rawstring)来调试它时犯了一个错误。我已经相应地更新了问题。感谢您对ipython中repr的澄清。我用脚本更新了问题。我希望有人能从中看出我做错了什么。@ephesian:你能再试试我的建议吗?老兄,非常感谢你!这是一个伟大的解决方案!到现在为止,我对编解码器一无所知。
struct.unpack('BBB', packet)
struct.unpack('BBB', packet.decode('string_escape'))