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?

¿Fue útil?

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'>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top