如何在没有python解释的情况下捕获二进制字符串中的所有字符

时间:2011-06-08 11:05:36

标签: python regex struct

以下是我重现问题的方法:

创建一个名为“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'”

4 个答案:

答案 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'))