我的日志文件中包含一些多行字节字符串,例如
[2019-05-25 19:16:31] b'logstring \ r \ n \ r \ nmore log'
尝试提取原始多行字符串后,如何将其转换为真实字符串 使用Python 3?
作为一个简化的示例,在读取日志文件并剥离时间之后,我最终得到了一个变量,该变量的类型为str,其前缀为b',作为字符串。
# note: b'' is inside the str (taken from log)
tmp = "b'logstring\r\n\r\nmore log'"
# convert here
print(tmp)
我正在寻找一种告诉python内容需要解码的方法。但是str不允许解码。
我想从打印命令中看到的结果是
logstring
more log
更新:“ eval”函数将产生此结果,但这将执行代码,因此不安全。
# note: b'' is inside the str (taken from log)
tmp = "b'logstring\r\n\r\nmore log'"
tmp = eval(tmp)
print(tmp)
有更好的方法吗?
答案 0 :(得分:1)
您可以使用正则表达式:
import re
tmp = "b'logstring\r\n\r\nmore log'"
r = re.compile(r"b'(.+)'", re.DOTALL|re.MULTILINE)
result = r.sub(r"\1", tmp)
print(result) # logstring\r\n\r\nmore log
您可以将其用于整个文件或逐行使用,但可能需要稍微更改此代码以满足您的需求。
-编辑-
如果要删除重复的换行符(如所需的输出所示),可以这样:
import re
tmp = "b'logstring\r\n\r\nmore log'"
binary_regex = re.compile(r"b'(.+)'", re.DOTALL|re.MULTILINE)
newline_regex = re.compile(r"(\r\n)+", re.DOTALL|re.MULTILINE)
# Make sure to do the compiles outside of any loops you have
result = binary_regex.sub(r"\1", tmp) # Remove the b''
result = newline_regex.sub(r"\r\n", result) # Remove duplicate new lines
print(result)
输出:
logstring
more log
答案 1 :(得分:0)
似乎您可以锁定eval函数,使其无法运行函数和python内置函数。您可以通过传递允许的全局和局部函数的字典来实现。 通过将所有内建函数映射为None,可以阻止常规python命令的执行。有了这个,使用eval评估字符串内容是安全的。
# note: b'' is inside the str (taken from log)
tmp = "b'logstring\r\n\r\nmore log'"
tmp = eval(tmp, {'__builtins__': None}, {})
print(tmp)
在上面的评论中,@ juanpa.arrivillaga提供了另一种解决方案,它也解决了评估安全问题:
import ast
tmp = "b'logstring\r\n\r\nmore log'"
tmp = ast.literal_eval(tmp)
print(tmp)
答案 2 :(得分:-1)
tmp = "b'logstring\r\n\r\n\r\nmore log'"
tmp = tmp[2:-1]
start_pos = tmp.find('\r')
end_pos =start_pos
for x in range (start_pos,len(tmp),2):
if tmp[x:x+1] == '\r' or tmp[x:x+1] == '\n':
end_pos +=2
if start_pos !=end_pos:
tmp = tmp[:start_pos] + '\r\n' + tmp[end_pos:]
print(tmp)
输出:
logstring
more log