从十六进制值之间的字符串中提取数据

时间:2014-12-23 17:36:57

标签: python

我有一个列表,只包含一个字符串,其中包含十六进制值,如\ x01,\ x02 ... 这些十六进制值永远不会出现在字符串的开头,也不会出现在字符串的末尾。

list1 = ["Test String\x01111\x05Test String\x02GG\x01TEXT123"]

我想提取该字符串中十六进制值之间的所有数据。因此,我要提取的数据是:Test String111Test StringGGTEXT123。 我怎么能这样做?

请注意,也可能有“空数据”:

                         # between \x01 and \x05 is nothing
list2 = ["Test String\x01\x05Test String2"]
                         # this should be saved even it is ""

此示例中的输出应为:Test StringEMPTY STRING(我的意思是“”),Test String2

3 个答案:

答案 0 :(得分:3)

这是re.split的一个很好的用例,其行为与str.split类似,但使用正则表达式(而不是字符串)作为分隔符。

当您说“十六进制值”时,我假设您的意思是“不可打印的ASCII字符”,即在0x000x1F0x7F的范围内。

>>> import re
>>> re.split('[\x00-\x1f\x7f]', 'Test String\x01111\x05Test String\x02GG\x01TEXT123')
['Test String', '111', 'Test String', 'GG', 'TEXT123']
>>> re.split('[\x00-\x1f\x7f]', 'Test String\x01\x05Test String2')
['Test String', '', 'Test String2']

答案 1 :(得分:1)

您可以在此处使用itertools.groupby对所有属于ASCII可打印范围的项目进行分组,对于不可打印范围内的项目,如果其组长度大于1,则返回''

from itertools import groupby
def solve(s):                                           
    for k, g in groupby(s, lambda x: 32 <= ord(x) < 127):
        if k:
            yield ''.join(g)
        else:
            g = list(g)
            if len(g) > 1:
                yield ''
...                 
>>> s = "Test String\x01111\x05Test String\x02GG\x01TEXT123"
>>> list(solve(s))                           
['Test String', '111', 'Test String', 'GG', 'TEXT123']
>>> s = "Test String\x01\x05Test String2"    
>>> list(solve(s))
['Test String', '', 'Test String2']

答案 2 :(得分:1)

>>> import re    
>>> re.findall(r'[\x01-\x05]([^\x01-\x05]*)[\x01-\x05]', list1[0])
['111', 'GG']

您的“十六进制值,如\ x01,\ x02 ......”的规范有点含糊不清 - 我假设为了上面的代码段“包含在\ x01和\ x05之间的值” - 如果你需要一个不同范围的“十六进制值”,当然很容易调整。

关键的想法是找到“一个hex value,然后是零个或多个non-hex values,然后找到一个hex value”,并通过将其封闭在中间来获得“零或更多”中心部分括号,从而使其成为正则表达式中的。这样,findall将返回所有群组内容的列表,这些内容似乎符合您的要求。