Python 3 字符串解码

4
我是一名有用的助手,可以为您翻译文本。
我从Apache日志文件中读取数据。有些文本是编码的。就像这一行一样:
192.168.1.17 - - [04/Aug/2016:18:45:00 +0800] "GET /d/?q=\xa9\xfa\xa4\xd1\xb7|\xa7\xf3\xa6n HTTP/1.1" 302 3734 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"

我想解码'\xa9\xfa\xa4\xd1\xb7|\xa7\xf3\xa6n'。
在Python 2中,我使用以下代码:
print(line.decode('string-escape').decode('big5'))

结果是:

这个标签:

明天會更好

但我无法用Python 3编写正确的代码。
我尝试使用以下代码:
with open('access.log', 'r') as f:
    line = f.read()
    print(bytes(line, 'latin-1').decode('big5'))

结果:

\xa9\xfa\xa4\xd1\xb7|\xa7\xf3\xa6n

或者这段代码:
with open('access.log', 'rb') as f:
    line = f.read()
    print(line.decode('big5'))

结果为:
\xa9\xfa\xa4\xd1\xb7|\xa7\xf3\xa6n

似乎是因为使用Python 3从文件中读取时,'\x'变成了'\x'。所以有人能帮我解决这个问题吗?谢谢。

1个回答

3
如果文件中有"\xDD",和 Python 代码中不同 - 在 Python 代码中,"\xDD" 序列在编译时被翻译,在程序内存中,只保留十六进制数字 "DD" 表示的字节。如果从文件中读取"x\DD"序列,在程序内存中将会有四个字节 - 每个 ASCII 字符对应一个字节。例如 "\xa9" ,在内存中有 "\"、"x"、"a"、"9" 四个字符(在 Python 中,“编译时间”是运行程序时发生的透明步骤)。
因此,如果你读取了一段在 Python3 中打印出来像 "\xa9\xfa" 的序列,但实际上应该看到 "明" 的话,你需要执行以下操作:
  1. 将字符串透明地转换为 bytes 对象(使用 latin1 编码)-(或者以二进制模式打开文件并将其读取为 bytes 对象)
  2. 使用 "unicode_escape" 编解码器将对象转换回文本。这将把"\xDD"序列解析成单个字节。

  3. 透明地将您的 unicode 对象转换为 bytes 对象(是的,再次) - 这次不是四个字符 "\,x,a,9",而是字节对象中仅有一个 0xa9 (169)字节存在于内存位置。

  4. 再次使用 big5 编码解码这个字节对象,那么你就得到了一个带有所需中文字符的字符串对象(文本)。

最后的 str 对象可以在任何支持这些字符的终端或 GUI 界面中打印出来(打印接口应该会从 Python 字符串透明地做最后的编码转换)。如果要将这些字符写入文件并使用 BIG5 编码,则在写入文件时显式指定该编码。 (或者根据您的系统使用 utf-8)。
因此,在代码中,需要执行以下操作:
with open('access.log', 'r') as f:
    line = f.read()
    step1 = line.encode("latin1")
    step2 = step1.decode("unicode_escape")
    step3 = step2.encode("latin1")
    final_text = step3.decode("big5")
    print(final_text)

TL;DR 在Python3中,"string_scape"编解码器是"unicode_escape" - 但你必须先将其应用于解码字节对象。


谢谢。你的代码有效。with open('access.log', 'r') as f: line = f.read() step1 = line.encode("latin1") step2 = step1.decode("unicode_escape") step3 = step2.encode("latin1") final_text = step3.decode("big5") print(final_text) - Steve.N

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接