2016-04-12 2 views
6

Viele Text-Kodierungen haben die Eigenschaft, dass Sie kodierten Text rückwärts durchlaufen können und immer noch in der Lage sein, es zu entschlüsseln. ASCII, UTF-8, UTF-16 und UTF-32 haben alle diese Eigenschaft. So können Sie beispielsweise die letzte Zeile einer Datei lesen, ohne alle Zeilen davor zu lesen, oder einige Zeilen von Ihrer aktuellen Position in einer Datei zurückgehen.Unicode-Text rückwärts dekodieren

Leider scheint Python mit keiner Möglichkeit zu kommen, eine Datei rückwärts zu dekodieren. Sie können nicht read rückwärts oder seek nach Zeichenanzahl in einer codierten Datei. Die Decoder im Modul codecs unterstützen die inkrementelle Dekodierung weiterleiten, aber nicht rückwärts. Es scheint keinen "UTF-8-rückwärts" -Codec zu geben, ich könnte UTF-8-Bytes in umgekehrter Reihenfolge einspeisen.

Ich könnte wahrscheinlich die Codec-abhängige Zeichengrenze Synchronisation selbst implementieren, binäre Stücke rückwärts lesen, und richtig ausgerichtete Chunks zu entsprechenden Decodern aus dem codecs-Modul, aber das klingt wie die Art, wo ein Nicht-Experte würde würde vermisse einige subtile Details und merke nicht, dass die Ausgabe falsch ist.

Gibt es eine einfache Möglichkeit, Text in Python mit vorhandenen Tools rückwärts zu dekodieren?


Einige Leute scheinen den Punkt verpasst zu haben, dass die gesamte Datei zu lesen, dies zu tun Niederlagen der Zweck. Während ich die Dinge klärt, könnte ich auch hinzufügen, dass dies für die Codierung mit variabler Länge auch funktionieren muss. UTF-8-Unterstützung ist ein Muss.

+0

Mögliche Duplikat [Lesen einer Datei in umgekehrter Reihenfolge mit Python] (http : //stackoverflow.com/questions/2301789/read-a-file-in-reverse-order-using-python) – gravity

+0

@gravity: Das liest die gesamte Datei. Ich versuche speziell, das nicht zu tun. – user2357112

+0

Dort gibt es eine spezifische Community-Wiki-Antwort, die das Lesen in Chunks beinhaltet. Bitte werfen Sie einen Blick auf diesen direkten Link: http://stackoverflow.com/questions/260273/most-efficient-way-to-search-the-last-x-lines-of-a-file-in-python/260433 # 260433 – gravity

Antwort

4

Ohne eine Allzwecklösung, hier ist ein speziell auf utf-8:

def rdecode(it): 
    buffer = [] 
    for ch in it: 
     och = ord(ch) 
     if not (och & 0x80): 
      yield ch.decode('utf-8') 
     elif not (och & 0x40): 
      buffer.append(ch) 
     else: 
      buffer.append(ch) 
      yield ''.join(reversed(buffer)).decode('utf-8') 
      buffer = [] 

utf8 = 'ho math\xc4\x93t\xc4\x93s hon \xc4\x93gap\xc4\x81 ho I\xc4\x93sous' 
print utf8.decode('utf8') 
for i in rdecode(reversed(utf8)): 
    print i, 
print "" 

Ergebnis:

$ python x.py 
ho mathētēs hon ēgapā ho Iēsous 
s u o s ē I o h ā p a g ē n o h s ē t ē h t a m o h 
+0

Das sieht so aus, wie ich es mir für den Fall "Implementiere es selbst" gedacht habe, obwohl es keine der Optimierungsmöglichkeiten für Chunks enthält, die man für die Arbeit mit echten Dateien benötigt. Ich denke, viele der Arbeiten, mit denen ich nicht zu tun hatte, waren wirklich in mehrfacher Codec-Unterstützung und dem Schreiben eines praktischen, effizienten Dateiobjekts, das 'read'-vorwärts- und rückwärts- und rückwärts-Iterationen unterstützt; Für nur UTF-8 ist die Decodierung selbst nicht zu schlecht. – user2357112