2008-10-06 17 views

Respuesta

41

Puede convertir el archivo con la misma facilidad utilizando la función unicode, pero tendrá problemas con los caracteres Unicode sin un equivalente ASCII directo.

This blog recomienda el módulo unicodedata, que parece ocuparse de la conversión aproximada de caracteres sin los valores ASCII correspondientes directos, p.

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

se suelen convertir en

Klft skrms infr p fdral lectoral groe 

que es bastante malo. Sin embargo, utilizando el módulo unicodedata, el resultado puede ser mucho más cerca del texto original:

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

Ese es bastante bueno, excepto que (como se señaló) omite algunos caracteres. Para Latin-1, necesitas casos especiales Æ, Ð, Ø, Þ, æ, ð, ø, ß, y special. – giltay

+0

Fredrick Lundh publicó sobre esto, con un simple script para construir sobre 'unicodedata' para reemplazos de casos especiales: http://effbot.org/zone/unicode-convert.htm – rcoup

11

Creo que este es un problema más profundo de lo que cree. Simplemente cambiar el archivo de Unicode a ASCII es fácil, sin embargo, obtener todos los caracteres Unicode para traducir en contrapartes ASCII razonables (muchas letras no están disponibles en ambas codificaciones) es otro.

Este Unicode de Python tutorial le puede dar una mejor idea de lo que ocurre con las cadenas Unicode que se convierten a ASCII: http://www.reportlab.com/i18n/python_unicode_tutorial.html

He aquí una cita útil desde el sitio:

Python 1.6 también para crear una "unicode" función incorporada, a la que se puede especificar la codificación :

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

Los tres de éstos regresan al mismo cosa, ya que los personajes de 'Hola' son comunes a las tres codificaciones.

Ahora codifiquemos algo con un acento europeo , que está fuera de ASCII. Lo que ve en una consola puede depender de la configuración regional de su sistema operativo ; Windows me permite escribir en ISO-Latin-1.

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

Si usted no puede escribir una carta aguda e, puede introducir la cadena 'Andr \ 202', que es inequívoca.

Unicode admite todas las operaciones comunes, como la iteración y la división . No correremos sobre ellos aquí.

+1

Gracias por señalar los posibles problemas. Sin embargo, no corro el riesgo de tener caracteres Unicode no convertibles dentro del contenido del archivo de salida.Simplemente está generando el esquema SQL de una base de datos interna y no contiene ningún carácter fuera de lo común, es decir, más allá de ASCII. –

+1

@Ray Vega: Eso lo sabes en este momento. Es un error y posible error suponer que los datos Unicode solo tendrán caracteres ASCII. –

2

De esta manera:

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

Tenga en cuenta, sin embargo, que esto será fallan con una excepción UnicodeDecodeError si hay caracteres que no pueden ser convertidos en ASCII.

EDITAR: Como acaba de señalar Pete Karl, no existe una correspondencia uno a uno desde Unicode a ASCII. Por lo tanto, algunos personajes simplemente no se pueden convertir de una manera que preserve la información. Además, ASCII estándar es más o menos un subconjunto de UTF-8, por lo que realmente no necesita hacer ninguna decodificación.

2

Aquí hay un código simple (y estúpida) para hacer la traducción de codificación. Asumo (pero no debería) 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 al mismo caracteres ASCII. Puede hacer lo siguiente para convertir caracteres no reconocidos en s '?':

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

Salida the docs para las opciones más simples. Si necesita hacer algo más sofisticado, puede consultar The UNICODE Hammer en el Python Cookbook.

0

Es importante tener en cuenta que no existe un formato de archivo 'Unicode'. Unicode se puede codificar a bytes de varias maneras diferentes. Más comúnmente UTF-8 o UTF-16. Necesitará saber cuál está generando su herramienta de terceros. Una vez que sabe que, 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 observa en las otras respuestas, lo que probablemente va a querer suministrar un controlador de errores con el método de codificación. Usar 'reemplazar' como manejador de errores es simple, pero destruirá su texto si contiene caracteres que no se pueden representar en ASCII.

0

Como han señalado otros carteles, ASCII es un subconjunto de Unicode.

Sin embargo, si usted:

  • tiene una aplicación de legado
  • no controlar el código para esa aplicación
  • usted es que su entrada cae en el subconjunto ASCII

A continuación, el ejemplo siguiente muestra cómo hacerlo:

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

myasciistring = (mystring.encode('ASCII')) 
type(myasciistring) 
    <type 'str'> 
2

Por mi problema en el que sólo quería saltar los caracteres no ASCII y salida sólo sólo de salida ASCII, la solución más adelante funcionó muy bien:

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

Por cierto, estos es un comando de Linux iconv para hacer esto tipo de trabajo.

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