我有base64编码的字符串,但最后有时会出现一些尾随垃圾,它总是以没有有效的base64字符开头。如何从开头提取有效字符串到第一个没有base64有效字符?
例如:
data = "(there is more valid content)gw3AQEFGh8NFgoqDwYsAQALDVFPVltYVkNGXldCRFUbNRk=----------:jhawrewre:--\r\n"
且有效部分没有"----------:jhawrewre:--\r\n"
valid = "(there is more valid content)gw3AQEFGh8NFgoqDwYsAQALDVFPVltYVkNGXldCRFUbNRk="
答案 0 :(得分:1)
您可以使用正则表达式删除无效部分:
import re
invalid_tail = re.compile(r'[^a-zA-Z0-9+/=\n\r].*$')
def remove_tail(base64_value):
return invalid_tail.sub('', base64_value)
[^a-zA-Z0-9+/=\n\r]
匹配任何不有效Base64字符的字符,加上尾随=
填充和换行符和回车符(在编码值中允许换行)线)。
演示:
>>> example = 'The quick brown fox jumps over the lazy dog!'.encode('base64')
>>> remove_tail(example + '*This is a tail').decode('base64')
'The quick brown fox jumps over the lazy dog!'
或者,使用样本的可解码部分:
>>> data = "3AQEFGh8NFgoqDwYsAQALDVFPVltYVkNGXldCRFUbNRk=----------:jhawrewre:--\r\n"
>>> remove_tail(data).decode('base64')
'\xdc\x04\x04\x14h|4X(\xa8<\x18\xb0\x04\x00,5E=YmaY\r\x19y]\t\x11Tl\xd4d'
此解决方案在速度上轻松胜过itertools.takewhile()
选项:
>>> import timeit
>>> text = "gw3AQEFGh8NFgoqDwYsAQALDVFPVltYVkNGXldCRFUbNRk=----------:jhawrewre:--\r\n"
>>> timeit.timeit('test(text)', 'from __main__ import with_takewhile as test, text')
11.785380125045776
>>> timeit.timeit('test(text)', 'from __main__ import with_re as test, text')
1.480334997177124
对于这个简单的样本,使用正则表达式几乎快10倍;对于较长的文本,结果会更快。
答案 1 :(得分:1)
您可以使用itertools.takewhile
:
创建一个迭代器,只要从iterable返回元素
predicate
是真的。
<强>演示:强>
>>> from itertools import takewhile
>>> from string import letters,digits
>>> valid_chars = letters + digits + '+/='
>>> text = "gw3AQEFGh8NFgoqDwYsAQALDVFPVltYVkNGXldCRFUbNRk=----------:jhawrewre:--\r\n"
>>> "".join(takewhile(lambda x:x in valid_chars, text))
'gw3AQEFGh8NFgoqDwYsAQALDVFPVltYVkNGXldCRFUbNRk='