2016-08-04 10 views
3

Ich lese Daten aus Apache Log-Datei. Es gibt einige Texte, die kodiert sind. Wie dieser Zeile:Python 3 string decode

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" 

Ich möchte entschlüsseln '\ xA9 \ xfa \ XA4 \ xd1 \ XB7 | \ xa7 \ XF3 \ xa6n'.

In Python 2, verwende ich den Code:

print(line.decode('string-escape').decode('big5')) 

Das Ergebnis:

明天會更好 

Aber ich kann den richtigen Code in Python nicht schreiben 3.

Ich versuche, Verwende den Code:

with open('access.log', 'r') as f: 
    line = f.read() 
    print(bytes(line, 'latin-1').decode('big5')) 

Das Ergebnis t:

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

Oder dieser Code:

with open('access.log', 'rb') as f: 
    line = f.read() 
    print(line.decode('big5')) 

Das Ergebnis:

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

Es scheint, weil mit Dateilese Form Python 3, die '\ x' wird '\ x' . Also, wenn mir jemand hilft, dieses Problem zu lösen? Vielen Dank.

Antwort

2

Wenn Sie das "\ xDD" in einer Datei haben, ist es anders als wenn sie in Python-Code sind - im Python-Code wird die "\ xDD" -Sequenz zur Kompilierzeit übersetzt, und im Programmspeicher nur Byte, das durch die Hexadezimalziffern "DD" dargestellt wird, wird beibehalten. Wenn Sie die "x \ DD" -Sequenz aus einer Datei lesen, gibt es im Programmspeicher vier Bytes - eins für jedes ASCII-Zeichen der Sequenz - also für "\ xa9" haben Sie im Speicher die Zeichen "\", "x", "a", "9" ("Kompilierzeit" in Python ist ein transparenter Schritt, der passiert, wenn man das Programm ausführt).

Also, wenn Sie haben eine Sequenz gelesen, die in Python3, wenn auf Ihrem Terminal zeigen gedruckt Sie eine Sequenz wie „\ xA9 \ xfa“, wenn Sie sollten sehen werden „明“ Sie, dies zu tun haben:

  1. Transparentes den String in ein Byte-Objekt konvertieren (den latin1-Codec) - (oder Ihre Datei als Byte-Objekt gelesen, es in binär-Modus zu öffnen zu beginnen mit)
  2. Decode Ihr Objekt zurück zum Text mit der "unicode_escape" Codec. Dies wird die "\ xDD" -Sequenzen in einzelne Bytes im Speicher parsen.

  3. konvertieren Transparentes Ihr Unicode-Objekt in Bytes (ja, wieder) - diesmal anstelle von vier Zeichen "\, x, a, 9" das Bytes Objekt einen einzigen 0xA9 hat (169) Byte in der Speicherposition .

  4. Entschlüsseln Sie von diesem Byte-Objekt erneut zu einer Zeichenfolge, diesmal mit der Big5-Decodierung. Es geben Sie - Sie ein String-Objekt haben (Text) mit dem gewünschten chinesischen Schriftzeichen,

Dieses letzte str Objekt, das in einer beliebigen Endgerät oder GUI-Schnittstelle druckbar ist, die die Zeichen (die Druckschnittstelle unterstützt, soll die letzte tun Kodierung Umwandlung transparent aus der Python-String).Wenn Sie diese Zeichen mithilfe der BIG5-Codierung in eine Datei schreiben möchten, übergeben Sie diese explizit, wenn Sie die zu schreibende Datei öffnen. (Oder benutzen Sie utf-8, abhängig von Ihrem System).

SO, in Code, das heißt:

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 In Python3, die "string_scape" Codec "unicode_escape" - aber Sie haben anwenden es ein Byte Objekt Decodierung mit zu beginnen .

+0

Vielen Dank. Dein Code funktioniert. mit offenem ('access.log', 'R') wie f: line = f.read() Schritt1 = line.encode ("latin1") Schritt 2 = step1.decode ("unicode_escape") step3 = step2.encode ("latin1") final_text = step3.decode ("big5") drucken (final_text) –