Domanda

Uso uno strumento di terze parti che genera un file in formato Unicode. Tuttavia, preferisco che sia in ASCII. Lo strumento non ha impostazioni per modificare il formato del file.

Qual è il modo migliore per convertire l'intero formato di file usando Python?

È stato utile?

Soluzione

Puoi convertire il file abbastanza facilmente usando la funzione unicode , ma incontrerai problemi con i caratteri Unicode senza un equivalente ASCII semplice.

Questo blog raccomanda il unicodedata , che sembra occuparsi della conversione approssimativa di caratteri senza diretta corrispondenti valori ASCII, ad es.

>>> title = u"Klüft skräms inför på fédéral électoral große"

viene in genere convertito in

Klft skrms infr p fdral lectoral groe

che è piuttosto sbagliato. Tuttavia, usando il modulo unicodedata , il risultato può essere molto più vicino al testo originale:

>>> import unicodedata
>>> unicodedata.normalize('NFKD', title).encode('ascii','ignore')
'Kluft skrams infor pa federal electoral groe'

Altri suggerimenti

Penso che questo sia un problema più profondo di quanto pensiate . Semplicemente cambiare il file da Unicode in ASCII è facile, tuttavia, far tradurre tutti i caratteri Unicode in ragionevoli controparti ASCII (molte lettere non sono disponibili in entrambe le codifiche) è un altro.

Questo tutorial Unicode di Python può darti un'idea migliore di cosa succede alle stringhe Unicode tradotte in ASCII: http://www.reportlab.com/i18n/python_unicode_tutorial.html

Ecco una citazione utile dal sito:

  

Python 1.6 ottiene anche un " unicode "   funzione integrata, a cui è possibile   specifica la codifica:

> >>> unicode('hello') u'hello'
> >>> unicode('hello', 'ascii') u'hello'
> >>> unicode('hello', 'iso-8859-1') u'hello'
> >>>
  

Tutti e tre questi restituiscono lo stesso   cosa, dal momento che i personaggi in 'Ciao'   sono comuni a tutte e tre le codifiche.

     

Ora codifichiamo qualcosa con a   Accento europeo, che è al di fuori di   ASCII. Quello che vedi in una console può   dipende dal tuo sistema operativo   locale; Windows mi permette di digitare   ISO-Latin-1.

> >>> a = unicode('André','latin-1')
> >>> a u'Andr\202'
  

Se non riesci a digitare una lettera acuta e,   puoi inserire la stringa 'Andr \ 202',   che è inequivocabile.

     

Unicode supporta tutti i comuni   operazioni come iterazione e   splitting. Non li investiremo   qui.

A proposito, questo è un comando linux iconv per fare questo tipo di lavoro.

iconv -f utf8 -t ascii <input.txt >output.txt

Ecco alcuni semplici (e stupidi) codici per eseguire la codifica della traduzione. Suppongo (ma non dovresti) che il file di input sia in UTF-16 (Windows lo chiama semplicemente "Unicode").

input_codec = 'UTF-16'
output_codec = 'ASCII'

unicode_file = open('filename')
unicode_data = unicode_file.read().decode(input_codec)
ascii_file = open('new filename', 'w')
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec)))

Nota che questo non funzionerà se ci sono caratteri nel file Unicode che non sono anche caratteri ASCII. Puoi fare quanto segue per trasformare i caratteri non riconosciuti in "?":

ascii_file.write(unicode_data.write(unicode_data.encode(output_codec, 'replace')))

Dai un'occhiata a i documenti per scelte più semplici. Se devi fare qualcosa di più sofisticato, ti consigliamo di dare un'occhiata a The UNICODE Hammer all'indirizzo il ricettario di Python.

In questo modo:

uc = open(filename).read().decode('utf8')
ascii = uc.decode('ascii')

Nota, tuttavia, che ciò fallirà con un'eccezione UnicodeDecodeError se ci sono caratteri che non possono essere convertiti in ASCII.

EDIT: come ha appena sottolineato Pete Karl, non esiste un mapping uno a uno da Unicode ad ASCII. Quindi alcuni personaggi semplicemente non possono essere convertiti in modo da preservare le informazioni. Inoltre, ASCII standard è più o meno un sottoinsieme di UTF-8, quindi non è nemmeno necessario effettuare alcuna decodifica.

Per il mio problema in cui volevo solo saltare i caratteri Non ascii e generare solo l'output ASCII, la soluzione di seguito ha funzionato davvero bene:

    import unicodedata
    input = open(filename).read().decode('UTF-16')
    output = unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')

È importante notare che non esiste un formato di file "Unicode". Unicode può essere codificato in byte in diversi modi. Più comunemente UTF-8 o UTF-16. Dovrai sapere quale strumento di terze parti sta producendo. Una volta che lo sai, la conversione tra diverse codifiche è abbastanza semplice:

in_file = open("myfile.txt", "rb")
out_file = open("mynewfile.txt", "wb")

in_byte_string = in_file.read()
unicode_string = bytestring.decode('UTF-16')
out_byte_string = unicode_string.encode('ASCII')

out_file.write(out_byte_string)
out_file.close()

Come notato nelle altre risposte, probabilmente vorrai fornire un gestore degli errori al metodo di codifica. Usare 'sostituisci' come gestore degli errori è semplice, ma manterrà il testo se contiene caratteri che non possono essere rappresentati in ASCII.

Come hanno notato altri poster, ASCII è un sottoinsieme di Unicode.

Tuttavia se:

  • dispone di un'app legacy
  • non controlli il codice per quell'app
  • sei sicuro che il tuo input rientri nel sottoinsieme ASCII

Quindi l'esempio seguente mostra come farlo:

mystring = u'bar'
type(mystring)
    <type 'unicode'>

myasciistring = (mystring.encode('ASCII'))
type(myasciistring)
    <type 'str'>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top