我有一个列表,只包含一个字符串,其中包含十六进制值,如\ x01,\ x02 ... 这些十六进制值永远不会出现在字符串的开头,也不会出现在字符串的末尾。
list1 = ["Test String\x01111\x05Test String\x02GG\x01TEXT123"]
我想提取该字符串中十六进制值之间的所有数据。因此,我要提取的数据是:Test String
,111
,Test String
,GG
,TEXT123
。
我怎么能这样做?
请注意,也可能有“空数据”:
# between \x01 and \x05 is nothing
list2 = ["Test String\x01\x05Test String2"]
# this should be saved even it is ""
此示例中的输出应为:Test String
,EMPTY STRING
(我的意思是“”),Test String2
答案 0 :(得分:3)
这是re.split
的一个很好的用例,其行为与str.split
类似,但使用正则表达式(而不是字符串)作为分隔符。
当您说“十六进制值”时,我假设您的意思是“不可打印的ASCII字符”,即在0x00
到0x1F
加0x7F
的范围内。
>>> 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
将返回所有群组内容的列表,这些内容似乎符合您的要求。