2016-04-12 26 views
6

Molte codifiche di testo hanno la proprietà che è possibile passare attraverso il testo codificato indietro ed essere ancora in grado di decodificarlo. ASCII, UTF-8, UTF-16 e UTF-32 hanno tutti questa proprietà. Questo ti permette di fare cose utili come leggere l'ultima riga di un file senza leggere tutte le righe precedenti, o andare indietro di qualche riga dalla posizione corrente in un file.Decodifica testo Unicode all'indietro

Sfortunatamente, Python non sembra avere alcun modo di decodificare un file all'indietro. Non è possibile read indietro o seek per quantità di carattere in un file codificato. I decodificatori nel modulo codecs supportano la decodifica incrementale in avanti, ma non indietro. Non sembra esserci alcun codec "UTF-8-backwards" in grado di alimentare byte UTF-8 in ordine inverso.

Probabilmente potrei implementare la sincronizzazione dei limiti del carattere dipendente dal codec, leggere i blocchi binari all'indietro e inserire i blocchi allineati correttamente ai decodificatori appropriati dal modulo codecs, ma sembra il tipo di cosa in cui un utente non esperto manca qualche dettaglio sottile e non nota che l'uscita è sbagliata.

C'è un modo semplice per decodificare il testo in Python con gli strumenti esistenti?


Diverse persone sembrano aver perso il punto che leggere l'intero file per fare questo contrasta con l'obiettivo. Mentre sto chiarendo le cose, potrei aggiungere che lo deve funzionare anche per codifiche a lunghezza variabile. Il supporto UTF-8 è obbligatorio.

+0

Eventuali duplicati di [Continua a leggere un file in ordine inverso utilizzando python] (http : //stackoverflow.com/questions/2301789/read-a-file-in-reverse-order-using-python) – gravity

+0

@gravity: legge l'intero file. Sto specificatamente cercando di non farlo. – user2357112

+0

C'è una specifica risposta wiki della comunità che implica la lettura in blocchi. Si prega di dare un'occhiata a questo link diretto: http://stackoverflow.com/questions/260273/most-efficient-way-to-search-the-last-x-lines-of-a-file-in-python/260433 # 260433 – gravity

risposta

4

Assente una soluzione general-purpose, qui è uno specifico per 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 "" 

Risultato:

$ 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

Sembra proprio quello che stavo pensando per il caso "implementalo da solo", anche se non ha nessuna ottimizzazione chunking per il funzionamento su file reali. Immagino che gran parte del lavoro che non volevo affrontare fosse in realtà nel supporto di molti codec e nella scrittura di un oggetto file conveniente ed efficiente che supporta l'iterazione in avanti e indietro e indietro di read reading; solo per UTF-8, la decodifica in sé non è male. – user2357112