3

我在matlab中有一个单元格数组

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

我使用这些脚本,它们利用 matlab 的 hdf5write 函数将数组保存为 hdf5 格式。

然后我使用 pytables 将 hdf5 文件读入 python。元胞数组以 numpy 字符串数组的形式出现。我转换为列表,这是输出:

>>>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'

关于如何处理这个问题的任何建议?

4

3 回答 3

9

您可以通过以下方式删除所有非单词字符:

>>> 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'
于 2011-03-04T19:08:21.393 回答
1

它们实际上不在字符串中:您有未转义的控制字符,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)
于 2011-03-04T19:10:42.963 回答
0

您也可以在不导入re. 例如,如果您满足于只保留 ascii 字符:

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

于 2016-04-07T06:15:57.123 回答