我从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'。所以,如果有人帮我解决这个问题?谢谢。
答案 0 :(得分:2)
如果你有" \ xDD"在文件中它与Python代码中的不同 - 在Python代码中," \ xDD"序列在编译时被翻译,并且在程序存储器中,只是由十六进制数字" DD"表示的字节。保持。如果您阅读" x \ DD"来自文件的序列,在程序存储器中将有四个字节 - 一个用于序列的每个ASCII字符 - 所以对于 "版权所有\ xA9"你有记忆中的字符" \"," x"," a"," 9" ('编译时间'在Python中是一个透明的步骤,当一个人运行程序时会发生。)
所以,如果您已经阅读了Python3中的序列,那么当打印到您的终端时,您会看到类似" \ xa9 \ xfa"的序列。当你应该看到"明"你必须这样做:
使用" unicode_escape"将对象解码回文本编解码器。这将解析" \ xDD"在内存中序列成单个字节。
透明地将您的unicode对象转换为字节(是的,再次) - 这次不是四个字符" \,x,a,9" bytes对象在内存位置有一个0xa9(169)字节。
再次从这个bytes对象解码为一个字符串,这次使用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" - 但是你必须将它解码为一个字节对象来开始。