Как захватить все символы в двоичной строке без интерпретации Python - PullRequest
3 голосов
/ 08 июня 2011

Вот как я воспроизвожу проблему:

Создайте файл журнала с именем '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)

Iзапустите скрипт, используя temp.log в качестве аргумента скрипта.

Надеюсь, комментарии высветят мою проблему.Как я могу получить пакет переменных, который будет интерпретироваться как '\ x61 \ x62 \ x63' ??

ВНЕ: При первом редактировании этого вопроса я предполагал, что чтение строки из файла было таким же, какthis: line = "DEBUG: packetReceived '\ x61 \ x62 \ x63'", который сделал пакет == 'abc'

, однако фактически он такой же, как эта (с использованием необработанной строки) line = r "DEBUG: packetReceived'\ x61 \ x62 \ x63' "

Ответы [ 4 ]

5 голосов
/ 08 июня 2011

Python не интерпретирует строки, которые вы передаете регулярным выражениям.Скорее всего, escape-последовательности интерпретировались ранее, когда вы определили переменную line.Это работает правильно, например:

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

Печатает \x61\x62\x63.

2 голосов
/ 08 июня 2011
>>> re.compile(r"packetReceived '(.*)'").search(r"DEBUG: packetReceived '\x61\x62\x63'").group(1)
'\\x61\\x62\\x63'

Нет, эта строка не там, где ваша проблема.

1 голос
/ 08 июня 2011

Как описано в вашем вопросе, пакет равен и равен '\x61\x62\x63'. Его длина составляет 12 байтов, ни 15, ни 3 байта.

Что вас смущает, так это то, что ipython (который, как я понимаю, вы используете) и интерпретатор python отображают значения с помощью вызова repr(), который пытается отформатировать значения так, как это было бы в вашем коде. Поскольку обратные косые черты являются специальными в строковых константах Python, repr() отображает их дубликаты, как и в коде Python.

Это может быть полезно:

for char in packet:
    print("%5d %2s %2r" % (ord(char), char, char))

Подсчитайте своих персонажей и посмотрите, как они напечатаны. В первом столбце отображается порядковый номер символа, во втором столбце - сам символ, в третьем столбце - repr символа.

EDIT

Изменить последнюю строку:

struct.unpack('BBB', packet)

до:

struct.unpack('BBB', packet.decode('string_escape'))
1 голос
/ 08 июня 2011

Если вы уверены, что получаете двенадцать символов, а не только три, представленные как двенадцать, возможно, это просто печать строки, которая вызывает у вас горе.

Сравните:

>> 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...