¿Cómo convierto el formato de un archivo de Unicode a ASCII usando Python?
Pregunta
Utilizo una herramienta de terceros que genera un archivo en formato Unicode. Sin embargo, prefiero que esté en ASCII. La herramienta no tiene configuraciones para cambiar el formato del archivo.
¿Cuál es la mejor manera de convertir todo el formato de archivo usando Python?
Solución
Puede convertir el archivo fácilmente con la simple función de unicode
, pero tendrá problemas con los caracteres Unicode sin un equivalente ASCII directo.
Este blog recomienda el unicodedata
módulo, que parece ocuparse de convertir caracteres aproximadamente sin directivo valores ASCII correspondientes, por ejemplo,
>>> title = u"Klüft skräms inför på fédéral électoral große"
normalmente se convierte a
Klft skrms infr p fdral lectoral groe
que está bastante mal. Sin embargo, al utilizar el módulo unicodedata
, el resultado puede estar mucho más cerca del texto original:
>>> import unicodedata
>>> unicodedata.normalize('NFKD', title).encode('ascii','ignore')
'Kluft skrams infor pa federal electoral groe'
Otros consejos
Creo que este es un problema más profundo del que te das cuenta . Simplemente cambiar el archivo de Unicode a ASCII es fácil, sin embargo, conseguir que todos los caracteres de Unicode se traduzcan en equivalentes ASCII razonables (muchas letras no están disponibles en ambas codificaciones) es otra.
Este tutorial de Python Unicode puede darle una mejor idea de lo que sucede con las cadenas Unicode que se traducen a ASCII: http://www.reportlab.com/i18n/python_unicode_tutorial.html
Aquí hay una cita útil del sitio:
Python 1.6 también obtiene un " Unicode " función incorporada, a la que se puede Especifique la codificación:
> >>> unicode('hello') u'hello'
> >>> unicode('hello', 'ascii') u'hello'
> >>> unicode('hello', 'iso-8859-1') u'hello'
> >>>
Los tres devuelven lo mismo. cosa, ya que los personajes en 'Hola' Son comunes a las tres codificaciones.
Ahora vamos a codificar algo con una Acento europeo, que está fuera de ASCII. Lo que ves en una consola puede Depende de tu sistema operativo lugar; Windows me permite escribir ISO-Latin-1.
> >>> a = unicode('André','latin-1')
> >>> a u'Andr\202'
Si no puede escribir una letra e aguda, puede introducir la cadena 'Andr \ 202', lo que no es ambiguo.
Unicode soporta todos los comunes operaciones tales como iteración y terrible. No los atropellaremos. aquí.
Por cierto, este es un comando de Linux iconv
para hacer este tipo de trabajo.
iconv -f utf8 -t ascii <input.txt >output.txt
Aquí hay un código simple (y estúpido) para hacer la traducción de la codificación. Supongo (pero no deberías) que el archivo de entrada está en UTF-16 (Windows lo llama simplemente '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)))
Tenga en cuenta que esto no funcionará si hay caracteres en el archivo Unicode que no sean también caracteres ASCII. Puede hacer lo siguiente para convertir los caracteres no reconocidos en '?' S:
ascii_file.write(unicode_data.write(unicode_data.encode(output_codec, 'replace')))
Consulte los documentos para obtener opciones más simples. Si necesita hacer algo más sofisticado, puede consultar Hammer UNICODE en El libro de cocina de Python.
Me gusta esto:
uc = open(filename).read().decode('utf8')
ascii = uc.decode('ascii')
Sin embargo, tenga en cuenta que esto fallará con una excepción UnicodeDecodeError
si hay caracteres que no se pueden convertir a ASCII.
EDITAR: como Pete Karl acaba de señalar, no hay una asignación uno a uno de Unicode a ASCII. Por lo tanto, algunos caracteres simplemente no se pueden convertir de una manera que conserve la información. Además, el ASCII estándar es más o menos un subconjunto de UTF-8, por lo que ni siquiera es necesario descodificar nada.
Para mi problema en el que solo quería omitir los caracteres que no son ASCII y solo dar salida a ASCII, la siguiente solución funcionó muy bien:
import unicodedata
input = open(filename).read().decode('UTF-16')
output = unicodedata.normalize('NFKD', input).encode('ASCII', 'ignore')
Es importante tener en cuenta que no hay un formato de archivo 'Unicode'. Unicode puede codificarse a bytes de varias maneras diferentes. Más comúnmente UTF-8 o UTF-16. Necesitará saber cuál es la herramienta de terceros que está generando. Una vez que lo sabes, la conversión entre diferentes codificaciones es bastante fácil:
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()
Como se señaló en las otras respuestas, probablemente querrá proporcionar un controlador de errores al método de codificación. Usar 'reemplazar' como controlador de errores es simple, pero modificará el texto si contiene caracteres que no pueden representarse en ASCII.
Como han señalado otros carteles, ASCII es un subconjunto de Unicode.
Sin embargo, si usted:
- tener una aplicación heredada
- no controlas el código de esa aplicación
- está seguro de que su entrada cae en el subconjunto ASCII
Luego, el siguiente ejemplo muestra cómo hacerlo:
mystring = u'bar'
type(mystring)
<type 'unicode'>
myasciistring = (mystring.encode('ASCII'))
type(myasciistring)
<type 'str'>