2009-05-03 10 views
79

Tengo un texto que usa signos de puntuación Unicode, como doble comilla izquierda, comilla simple derecha para apóstrofo, y así sucesivamente, y lo necesito en ASCII. ¿Python tiene una base de datos de estos personajes con obvios sustitutos de ASCII, así que puedo hacerlo mejor que convertirlos a todos en "?" ?¿Dónde está la "mejor ASCII de Python para esta base de datos Unicode"?

+21

eres valiente guerrero. Unicode es el archienemigo de Python. –

+1

Las personas que encuentran esto pueden estar interesadas en [¿Cuál es la mejor manera de eliminar acentos en una cadena de Unicode de Python?] (Http://stackoverflow.com/q/517923/562769) –

Respuesta

84

Unidecode parece una solución completa. Convierte presupuestos sofisticados a citas ascii, acentúa caracteres latinos a incómodos e incluso intenta la transliteración para tratar con caracteres que no tienen equivalentes ASCII. De esta forma, tus usuarios no tienen que ver muchos? cuando tenía que pasar su texto a través de un sistema ascii heredado de 7 bits.

>>> from unidecode import unidecode 
>>> print unidecode(u"\u5317\u4EB0") 
Bei Jing 

http://www.tablix.org/~avian/blog/archives/2009/01/unicode_transliteration_in_python/

+3

Hm .. las diéresis alemanas se convierten en su carácter base en lugar de p. Ej. ö = oe, ä = ae, etc. – ThiefMaster

+4

@ThiefMaster son esos equivalentes verdaderos en todos los idiomas? Tal vez Unidecode busca el mínimo común denominador. –

+0

Unidecode es sin duda la solución independiente del idioma. Para una solución centrada en Alemania, convierta los charecters aplicables manualmente ('s/ö/oe /', etc.) antes de limpiar el resto con 'unidecode'. – alexis

19

Interesante pregunta.

Google me ayudó a encontrar lo que this page descibes utilizando el unicodedata module como los siguientes:

import unicodedata 
unicodedata.normalize('NFKD', title).encode('ascii','ignore') 
+1

Útil, pero eso descarta la puntuación unicode . – joeforker

24

En mi respuesta original, también sugerí unicodedata.normalize. Sin embargo, decidí probarlo y resulta que no funciona con comillas Unicode. Hace un buen trabajo traduciendo caracteres Unicode acentuados, así que supongo que unicodedata.normalize se implementa utilizando la función unicode.decomposition, lo que me lleva a pensar que probablemente solo pueda manejar caracteres Unicode que sean combinaciones de una letra y una marca diacrítica, pero estoy no es realmente un experto en la especificación Unicode, así que podría estar lleno de aire caliente ...

En cualquier caso, puede usar unicode.translate para tratar los caracteres de puntuación. El método translate toma un diccionario de ordinales Unicode a los ordinales Unicode, por lo tanto usted puede crear una correlación que se traduce sólo Unicode puntuacion a ASCII-compatibles puntuacion:

'Maps left and right single and double quotation marks' 
'into ASCII single and double quotation marks' 
>>> punctuation = { 0x2018:0x27, 0x2019:0x27, 0x201C:0x22, 0x201D:0x22 } 
>>> teststring = u'\u201Chello, world!\u201D' 
>>> teststring.translate(punctuation).encode('ascii', 'ignore') 
'"hello, world!"' 

Puede añadir más asignaciones de puntuación, si es necesario, pero Don No creo que necesariamente tenga que preocuparse por manejar cada caracter de puntuación Unicode. Si do necesita manejar acentos y otras marcas diacríticas, igual puede usar unicodedata.normalize para tratar esos caracteres.

+0

Consulte también el paquete 'unidecode' – joeforker

3

Hay una discusión adicional sobre esto en http://code.activestate.com/recipes/251871/ que tiene la solución NFKD y algunas formas de hacer una tabla de conversión, para cosas como ± => +/- y otros caracteres que no sean letras.

Cuestiones relacionadas