Как удалить шестнадцатеричные значения в строке Python с регулярными выражениями? - PullRequest
3 голосов
/ 04 марта 2011

У меня есть массив ячеек в Matlab

columns = {'MagX', 'MagY', 'MagZ', ...
           'AccelerationX',  'AccelerationX',  'AccelerationX', ...
           'AngularRateX', 'AngularRateX', 'AngularRateX', ...
           'Temperature'}

Я использую эти сценарии , в которых используется функция hdf5write matlab для сохранения массива в формате hdf5.

Затем я прочитал в файле hdf5 на python, используя pytables. Массив ячеек представлен в виде массива строк. Я конвертирую в список, и это вывод:

>>>columns
['MagX\x00\x00\x00\x08\x01\x008\xe6\x7f',
 'MagY\x00\x7f\x00\x00\x00\xee\x0b9\xe6\x7f',
 'MagZ\x00\x00\x00\x00\x001',
 'AccelerationX',
 'AccelerationY',
 'AccelerationZ',
 'AngularRateX',
 'AngularRateY',
 'AngularRateZ',
 'Temperature']

Эти шестнадцатеричные значения попадают в строки откуда-то, и я хотел бы их удалить. Они не всегда появляются в первых трех пунктах списка, и мне нужен хороший способ разобраться с ними или выяснить, почему они там находятся.

>>>print columns[0]
Mag8�
>>>columns[0]
'MagX\x00\x00\x00\x08\x01\x008\xe6\x7f'
>>>repr(columns[0])
"'MagX\\x00\\x00\\x00\\x08\\x01\\x008\\xe6\\x7f'"
>>>print repr(columns[0])
'MagX\x00\x00\x00\x08\x01\x008\xe6\x7f'

Я пытался использовать регулярное выражение для удаления шестнадцатеричных значений, но мне немного не повезло.

>>>re.sub('(\w*)\\\\x.*', '\1', columns[0])
'MagX\x00\x00\x00\x08\x01\x008\xe6\x7f'
>>>re.sub('(\w*)\\\\x.*', r'\1', columns[0])
'MagX\x00\x00\x00\x08\x01\x008\xe6\x7f'
>>>re.sub(r'(\w*)\\x.*', '\1', columns[0])
'MagX\x00\x00\x00\x08\x01\x008\xe6\x7f'
>>>re.sub('([A-Za-z]*)\x00', r'\1', columns[0])
'MagX\x08\x018\xe6\x7f'
>>>re.sub('(\w*?)', '\1', columns[0])
'\x01M\x01a\x01g\x01X\x01\x00\x01\x00\x01\x00\x01\x08\x01\x01\x01\x00\x018\x01\xe6\x01\x7f\x01'

Есть предложения, как с этим бороться?

Ответы [ 3 ]

7 голосов
/ 04 марта 2011

Вы можете удалить все несловарные символы следующим образом:

>>> re.sub(r'[^\w]', '', 'MagX\x00\x00\x00\x08\x01\x008\xe6\x7f')
'MagX8'

Регулярное выражение [^\w] будет соответствовать любому символу, который не является буквой, цифрой или подчеркиванием. Предоставив это регулярное выражение в re.sub с пустой строкой в ​​качестве замены, вы удалите все остальные символы в строке.

Поскольку могут быть другие символы, которые вы хотите сохранить, лучшим решением может быть указание большего диапазона символов, который вы хотите сохранить, исключая управляющие символы. Например:

>>> re.sub(r'[^\x20-\x7e]', '', 'MagX\x00\x00\x00\x08\x01\x008\xe6\x7f')
'MagX8'

Или вы можете заменить [^\x20-\x7e] эквивалентным [^ -~], в зависимости от того, что вам кажется более понятным.

Чтобы исключить все символы после этого первого управляющего символа, просто добавьте .*, например:

>>> re.sub(r'[^ -~].*', '', 'MagX\x00\x00\x00\x08\x01\x008\xe6\x7f')
'MagX'
1 голос
/ 04 марта 2011

На самом деле их нет в строке: у вас есть неэкранированные управляющие символы, которые Python отображает в шестнадцатеричном формате - вот почему вы видите необычный символ при печати значения.

Вы должны просто иметь возможностьчтобы удалить лишние уровни цитирования в вашем регулярном выражении, но вы также можете просто положиться на что-то вроде универсального класса пробела модуля regexp, который будет сопоставлять пробельные символы, кроме символов табуляции и пробелов:

>>> import re
>>> re.sub(r'\s', '?', "foo\x00bar")
'foo\x00bar'
>>> print re.sub(r'\s', '?', "foo\x00bar")
foobar

Я использую этоодин, чтобы заменить все входные пробелы, включая символы без пробелов, на один пробел:

>>> re.sub(r'[\xa0\s]+', ' ', input_str)
0 голосов
/ 07 апреля 2016

Вы также можете сделать это без импорта re. Например. если вы удовлетворены тем, что сохраняете только символы ascii:

good_string = ''.join(c if ord(c) < 129 else '?' for c in bad_string)

...