Как удалить шестнадцатеричные значения в строке Python с помощью регулярных выражений?

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

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

Я использую эти скрипты, которые используют функцию матлаба hdf5write для сохранения массива в формате 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'

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


person moorepants    schedule 04.03.2011    source источник


Ответы (3)


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

>>> 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'
person Andrew Clark    schedule 04.03.2011
comment
Спасибо, это просто и делает то, что мне нужно. Я слишком часто забываю использовать символ ^. - person moorepants; 04.03.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)
person Chris Adams    schedule 04.03.2011
comment
Знаете ли вы какие-либо ссылки, которые объясняют неэкранированные и экранированные управляющие символы? - person moorepants; 04.03.2011
comment
На самом деле это просто стандартное поведение строки Python: строки могут содержать двоичные значения, которые ваш терминал может интерпретировать при отображении содержимого (вот почему, например, случайное отображение двоичных данных может привести к изменению шрифта или звука системного звонка). ). Поскольку это бесполезно и несколько раздражает, интерактивная оболочка Python вместо этого будет отображать представление строки (например, что repr(foo) вернет), которое включает экранирование, необходимое для правильного ввода этой строки в источнике Python. - person Chris Adams; 04.04.2011

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

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

person Carl Smith    schedule 07.04.2016