以下是我重现问题的方法:
创建一个名为“temp.log”的日志文件并将此行粘贴到其中
DEBUG: packetReceived '\x61\x62\x63'
我想要一个脚本,它将从日志文件中读取行并解码二进制字符串部分('\ x61 \ x62 \ x63')。对于解码,我使用struct,所以:
struct.unpack('BBB', '\x61\x62\x63')
应该给我
(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)
我使用temp.log作为脚本的参数来运行脚本。
希望评论突出我的问题。如何将变量包解释为'\ x61 \ x62 \ x63'??
ASIDE:在第一次编辑这个问题时,我假设从文件中读取该行与此相同: line =“DEBUG:packetReceived'\ x61 \ x62 \ x63'” 这使得包=='abc'
然而它实际上与此相同(使用rawstring) line = r“DEBUG:packetReceived'\ x61 \ x62 \ x63'”
答案 0 :(得分:5)
Python不会解释传递给正则表达式的字符串。当您定义变量line
时,转义序列很可能更早被解释。这可以正常工作,例如:
line = r"DEBUG: packetReceived '\x61\x62\x63'"
print re.compile(r"packetReceived '(.*)'").search(line).group(1)
打印\x61\x62\x63
。
答案 1 :(得分:2)
>>> re.compile(r"packetReceived '(.*)'").search(r"DEBUG: packetReceived '\x61\x62\x63'").group(1)
'\\x61\\x62\\x63'
不,那条线不是你的问题所在。
答案 2 :(得分:1)
如果你确定你收到12个字符,而不只是三个字符代表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
答案 3 :(得分:1)
如您的问题所述,数据包 等于'\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)
为:
struct.unpack('BBB', packet.decode('string_escape'))