【问题标题】:Convert multiline bytestring, typed as string type to proper string将作为字符串类型键入的多行字节字符串转换为正确的字符串
【发布时间】:2019-05-29 16:16:06
【问题描述】:

我的日志文件中有一些多行字节串,比如

[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)

有没有更好的办法?

【问题讨论】:

  • 谢谢迈克,但这无济于事。导入的文本是字符串格式,因为“b”是日志文件的一部分。您链接到的问题没有解决这个问题
  • 你应该修复任何产生这个问题的东西。使用eval 是破解此问题解决方案的最直接方法。如果安全是一个问题,则使用import ast; ast.literal_eval 安全地评估表示字节文字的字符串,然后对其进行解码,但同样,修复此问题的根源
  • 谢谢,这行得通。关于修复源,我正在解析(现有)日志文件以提取数据,因此无法修复源。

标签: python python-3.x


【解决方案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

【讨论】:

  • r = re.compile(r"b'(.+)'", re.DOTALL|re.MULTILINE)
  • @Mike 谢谢。我没有太多的正则表达式练习。
【解决方案2】:

似乎您可以锁定 eval 函数,使其无法运行函数和 python 内置函数。您可以通过传递允许的全局和局部函数的字典来做到这一点。 通过将所有内置函数映射到 None,您可以阻止常规 python 命令的执行。有了这些,使用 eval 来评估字符串内容是安全的。

来源this article

# note: b'' is inside the str (taken from log)
tmp =  "b'logstring\r\n\r\nmore log'"
tmp = eval(tmp, {'__builtins__': None}, {}) 
print(tmp)

在上面的 cmets 中,@juanpa.arrivillaga 提供了另一种解决方案,也解决了 eval 安全问题:

import ast

tmp =  "b'logstring\r\n\r\nmore log'"
tmp = ast.literal_eval(tmp) 
print(tmp)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    相关资源
    最近更新 更多