2010-09-30 14 views
12

Estoy buscando una función simple de Python que toma una cadena y devuelve una similar pero con todos los caracteres no ASCII convertidos al equivalente ascii más cercano. Por ejemplo, signos diacríticos y otras cosas que deberían descartarse. Me imagino que debe haber una forma bastante canónica de hacer esto y hay muchas preguntas relacionadas con el stackoverflow, pero no encuentro una respuesta simple, por lo que me pareció digno de una pregunta por separado.Python regex para convertir caracteres no ascii en una cadena a los equivalentes ascii más cercanos

Ejemplo de entrada/salida:

"Étienne" -> "Etienne" 
+6

¿Cómo se define "más cercano"? – nmichaels

+0

¡Buena pregunta! Creo que espero no tener que definirlo, que hay algún mapeo estándar aceptado en alguna parte. Estoy seguro de que esto es más peludo de lo que imagino que es realmente correcto, pero las soluciones parciales también serían valiosas. – dreeves

+2

'iconv' puede hacerlo con un indicador' // TRANSLIT', aunque no está seguro si hay enlaces apropiados de Python. – Wrikken

Respuesta

1

Hacer una búsqueda de 'iconv TRANSLIT pitón' he encontrado: http://www.tablix.org/~avian/blog/archives/2009/01/unicode_transliteration_in_python/ que parece que podría ser lo que necesita. Los comentarios tienen otras ideas que usan la biblioteca estándar en su lugar.

También hay http://web.archive.org/web/20070807224749/http://techxplorer.com/2006/07/18/converting-unicode-to-ascii-using-python/ que usa NFKD para obtener los caracteres base siempre que sea posible.

2

En Python 3 y usando la aplicación de expresiones regulares en PyPI:

A partir de la cadena:

>>> s = "Étienne" 

Normalizar a NFKD y luego retire los diacríticos:

>>> import unicodedata 
>>> import regex 
>>> regex.sub(r"\p{Mn}", "", unicodedata.normalize("NFKD", s)) 
'Etienne' 
+1

Eso realmente no hace mucho. Por ejemplo, el punto de código U + 00F8, * ø *, ** no ** se descompone en algo con Marks. Pero todavía tiene la misma resistencia de colación primaria que * o * tiene: 138E por DUCET 6.0. Del mismo modo, no hay descomposición para el punto de código U + 00F0, * ð. * Sin embargo, su intensidad de intercalación primaria es la misma que * d * en 1250. Las personas necesitan aprender a trabajar * con * Unicode, ¡no en contra de ello! – tchrist

+0

He visto la biblioteca que mencionas y parece muy emocionante. ¿Eres tu autor?He estado interesado en una biblioteca de Python con mejor soporte de Unicode desde hace bastante tiempo. Déjame revisarlo y enviarte un correo. Muchas gracias. – tchrist

+0

Tu código muestra "Étienne" para mí ... – Cerin

1

Lee las respuestas a algunas de las preguntas duplicadas. El truco NFKD funciona solo como un separador de acentos. No maneja ligaduras y muchos otros caracteres latinos que no pueden (o no) descomponerse. Para esto, es necesaria una tabla de traducción preparada (y mucho más rápido).

+0

Gracias John. Realmente odio ver gente mutilando datos Unicode. Usualmente se debe a que no saben cómo hacer una comparación en la fuerza de compaginación 1 (primaria) solamente. Por ejemplo, en el nivel 1 hay 99 A, 43 B, 53 C, etc. O tiene la mayor cantidad en 111, Q la menor cantidad en 34. NFKD eleva esos números un poco, colocando A a 115 y O a 119, por ejemplo. – tchrist

Cuestiones relacionadas