【问题标题】:Pulling valid data from bytestring in Python 3在 Python 3 中从字节串中提取有效数据
【发布时间】:2013-02-07 06:56:45
【问题描述】:

给定以下字节串,我怎样才能删除任何匹配 \xFF 的字符,并从剩下的内容中创建一个列表对象(通过在删除的区域上拆分)?

b"\x07\x00\x00\x00~\x10\x00pts/5\x00\x00/5\x00\x00user\x00\x00"

想要的结果:

["~", "pts/5", "/5", "user"]

上面的字符串只是一个例子 - 我想删除任何 \x.. (非解码)字节。

我使用的是 Python 3.2.3,并且希望只使用标准库。

【问题讨论】:

    标签: python-3.x regex python-3.2


    【解决方案1】:
    >>> a = b"\x07\x00\x00\x00~\x10\x00pts/5\x00\x00/5\x00\x00user\x00\x00"
    >>> import re
    >>> re.findall(rb"[^\x00-\x1f\x7f-\xff]+", a)
    [b'~', b'pts/5', b'/5', b'user']
    

    结果仍然是bytes 对象。如果您希望结果是字符串:

    >>> [i.decode("ascii") for i in re.findall(rb"[^\x00-\x1f\x7f-\xff]+", a)]
    ['~', 'pts/5', '/5', 'user']
    

    说明:

    [^\x00-\x1f\x7f-\xff]+ 匹配一个或多个 (+) 字符,这些字符在 ASCII 0 和 31 (\x00-\x1F) 之间的范围 ([^...]) 或 ASCII 127 和 255 之间(\x7f-\xff)。

    请注意,这种方法仅适用于“嵌入文本”为 ASCII 的情况。它将从以 8 位代码页(如latin-1)编码的字符串中删除所有扩展的字母字符(如äé 等),并将有效地破坏以UTF-8 和其他编码的字符串Unicode 编码,因为它们确实包含 0 到 31/127 和 255 之间的字节值作为其字符代码的一部分。

    当然,您始终可以根据此答案中给出的示例手动微调要删除的确切范围。

    【讨论】:

    • 我必须将 re.findall(rb"pattern", a) 更改为 re.findall(b"pattern", a) 才能使其在 Ubuntu 12.10 (Python 3.2.3) 上运行,但是它做了。有些字符仍然可以通过,例如 \x7f 和 \x8e。我实际上不确定这个字节串是否是 UTF-8 - 它是 Linux 中的 open('/var/run/utmp', 'rb').read() 。
    • @wroberts:奇怪的是 Ubuntu 上的 Python 在处理原始字符串时会出现问题,但是是的,没有它们它确实可以工作(当存在其他不明确的转义序列时,这通常是正则表达式的一个有用习惯否则,如\b)。您也可以删除所有大于 ASCII 127 的字符。将编辑我的答案。
    猜你喜欢
    • 2014-05-15
    • 2016-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 2021-05-01
    相关资源
    最近更新 更多