String Python3字符串解码

String Python3字符串解码,string,python-3.x,unicode,String,Python 3.x,Unicode,我从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 |

我从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'))
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
\xa9\xfa\xa4\xd1\xb7|\xa7\xf3\xa6n
但是我不能用python 3编写正确的代码

我尝试使用以下代码:

print(line.decode('string-escape').decode('big5'))
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
\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
\xa9\xfa\xa4\xd1\xb7|\xa7\xf3\xa6n
似乎是因为用Python 3读取表单文件,'\x'变成了'\x'。如果有人帮我解决这个问题?谢谢。

如果文件中有“\xDD”,则与Python代码中的不同-在Python代码中,“\xDD”序列在编译时翻译,并且在程序内存中,只保留十六进制数字“DD”表示的字节。如果从文件中读取“x\DD”序列,程序内存中将有四个字节-序列的每个ASCII字符一个字节-因此 “\xa9”内存中有“\”、“x”、“a”、“9”等字符(Python中的“编译时”是一个透明的步骤,在运行程序时会发生)

因此,如果您阅读了Python3中的一个序列,当打印到终端时,会显示一个类似“\xa9\xfa”的序列,此时您应该看到”明" 你必须这样做:

  • 透明地将字符串转换为字节对象(使用 latin1编解码器)-(或将文件作为字节对象读取,然后在中打开它 以二进制模式开始)
  • 使用“unicode_escape”编解码器将对象解码回文本。这将在内存中将“\xDD”序列解析为单个字节

  • 透明地将unicode对象转换为字节(是的,再次)—— 这次,字节对象的内存位置将有一个0xa9(169)字节,而不是四个字符“\,x,a,9”

  • 再次将字节对象解码为字符串,这次使用big5解码。你有一个字符串对象(文本)和你想要的汉字

  • 可在支持字符的任何终端或GUI界面中打印的最后一个str对象(打印界面应透明地从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”-但您必须首先应用它来解码字节对象。

    谢谢。您的代码可以工作。使用open('access.log','r')作为f:line=f.read()step1=line.encode(“拉丁语”)step2=step1.解码(“unicode_-escape”)step3=step2.编码('拉丁语1“)最终文本=步骤3.解码(“big5”)打印(最终文本)