Tengo una cadena Unicode en Python, y me gustaría eliminar todos los acentos (signos diacríticos).
Encontré en la Web una forma elegante de hacer esto en Java:
- Convierta la cadena Unicode a su forma normalizada larga (con un carácter separado para letras y diacríticos)
- elimine todos los caracteres cuyo tipo Unicode sea "diacrítico".
¿Necesito instalar una biblioteca como pyICU o es posible solo con la biblioteca estándar de python? ¿Y qué hay de Python 3?
Nota importante: me gustaría evitar el código con una asignación explícita de caracteres acentuados a su contraparte no acentuada.
python
python-3.x
unicode
python-2.x
diacritics
MiniQuark
fuente
fuente
unidecode
reemplaza°
condeg
. Hace más que solo eliminar acentos.Qué tal esto:
Esto también funciona en letras griegas:
La categoría de caracteres "Mn" significa
Nonspacing_Mark
, que es similar a unicodedata.combining en la respuesta de MiniQuark (no pensé en unicodedata.combining, pero probablemente sea la mejor solución, porque es más explícita).Y tenga en cuenta que estas manipulaciones pueden alterar significativamente el significado del texto. Los acentos, Umlauts, etc. no son "decoración".
fuente
unicodedata.name
, o desglosar y usar una tabla similar, lo que necesitarías para las letras griegas de todos modos (Α es simplemente "ALFA GRÁFICA LETRA DE CAPITAL").A
. Si no lo quiere, no lo haga, pero en ambos casos está sustituyendo un parecido latino (cercano).ß
en ascii,ss
por ejemplo. Todavía lo usaríaunidecode
para evitar accidentes.Acabo de encontrar esta respuesta en la Web:
Funciona bien (para francés, por ejemplo), pero creo que el segundo paso (eliminar los acentos) podría manejarse mejor que soltar los caracteres que no son ASCII, porque esto fallará en algunos idiomas (griego, por ejemplo). La mejor solución probablemente sería eliminar explícitamente los caracteres unicode que están etiquetados como diacríticos.
Editar : esto hace el truco:
unicodedata.combining(c)
devolverá verdadero si el carácterc
se puede combinar con el carácter anterior, esto es principalmente si es un signo diacrítico.Edición 2 :
remove_accents
espera una cadena unicode , no una cadena de bytes. Si tiene una cadena de bytes, debe decodificarla en una cadena unicode como esta:fuente
nkfd_form = unicodedata.normalize('NFKD', unicode(input_str, 'utf8'))
, 'utf8'
es una "red de seguridad" necesaria si está probando la entrada en la terminal (que por defecto no usa unicode). Pero generalmente no tiene que agregarlo, ya que si está eliminando acentos,input_str
es muy probable que ya sea utf8. Sin embargo, no está de más estar a salvo.remove_accents
una cadena normal (u "é" en lugar de "é"). Pasó una cadena normal aremove_accents
, por lo que al intentar convertir su cadena en una cadena Unicode,ascii
se utilizó la codificación predeterminada . Esta codificación no admite ningún byte cuyo valor sea> 127. Cuando escribiste "é" en tu shell, tu sistema operativo lo codificó, probablemente con UTF-8 o alguna codificación de página de códigos de Windows, y eso incluyó bytes> 127. Cambiaré mi función para eliminar la conversión a Unicode: bombardeará más claramente si se pasa una cadena no Unicode.En realidad trabajo en proyectos compatibles con Python 2.6, 2.7 y 3.4 y tengo que crear ID a partir de entradas de usuario gratuitas.
Gracias a ti, he creado esta función que funciona de maravilla.
resultado:
fuente
text = unicode(text, 'utf-8')
. Una solución para eso fue agregarexcept TypeError: pass
Esto maneja no solo acentos, sino también "trazos" (como en ø, etc.):
Esta es la forma más elegante que se me ocurre (y alexis lo ha mencionado en un comentario en esta página), aunque no creo que sea muy elegante. De hecho, es más un truco, como se señala en los comentarios, ya que los nombres Unicode son, en realidad solo nombres, no dan garantía de ser coherentes ni nada.
Todavía hay letras especiales que no son manejadas por esto, como las letras invertidas, ya que su nombre unicode no contiene 'WITH'. Depende de lo que quieras hacer de todos modos. A veces necesitaba quitar el acento para lograr el orden de clasificación del diccionario.
EDITAR NOTA:
Sugerencias incorporadas de los comentarios (manejo de errores de búsqueda, código Python-3).
fuente
unicode
llamada de función allí con Python 3? Creo que una expresión regular más estricta en lugar de lafind
evitaría todos los problemas mencionados en el comentario anterior, y también, la memorización ayudaría al rendimiento cuando se trata de una ruta de código crítica.unicode
letra ya no es apropiado en Python 3. En cualquier caso, en mi experiencia no existe una solución universal y elegante para este problema. Dependiendo de la aplicación, cualquier enfoque tiene sus ventajas y desventajas. Herramientas prósperas como la calidadunidecode
se basan en tablas hechas a mano. Unicode proporciona algunos recursos (tablas, algoritmos), por ejemplo. por cotejo.En respuesta a la respuesta de @ MiniQuark:
Intenté leer en un archivo csv que era medio francés (con acentos) y también algunas cadenas que eventualmente se convertirían en enteros y flotantes. Como prueba, creé un
test.txt
archivo que se veía así:Tuve que incluir líneas
2
y3
hacerlo funcionar (que encontré en un ticket de Python), así como incorporar el comentario de @ Jabba:El resultado:
(Nota: estoy en Mac OS X 10.8.4 y estoy usando Python 2.7.3)
fuente
remove_accents
estaba destinado a eliminar acentos de una cadena unicode. En caso de que pase una cadena de bytes, intenta convertirla en una cadena unicode conunicode(input_str)
. Utiliza la codificación predeterminada de python, que es "ascii". Como su archivo está codificado con UTF-8, esto fallará. Las líneas 2 y 3 cambian la codificación predeterminada de Python a UTF-8, por lo que funciona, como descubrió. Otra opción es pasarremove_accents
una cadena Unicode: eliminar las líneas 2 y 3, y en la última línea reemplazarelement
porelement.decode("utf-8")
. Probé: funciona. Actualizaré mi respuesta para aclarar esto.iso-8859-1
, que no puedo ir a trabajar con esta función, por desgracia!)reload(sys); sys.setdefaultencoding("utf-8")
es un truco dudoso a veces recomendado para sistemas Windows; ver stackoverflow.com/questions/28657010/… para más detalles.gensim.utils.deaccent (texto) de Gensim - modelado de temas para humanos :
Otra solución es unidecode .
Tenga en cuenta que la solución sugerida con unicodedata generalmente elimina los acentos solo en algún carácter (por ejemplo, se convierte
'ł'
en''
, en lugar de en'l'
).fuente
deaccent
todavía da enł
lugar del
.NumPy
ySciPy
eliminar acentos.Algunos idiomas tienen diacríticos combinables como letras de idiomas y diacríticos de acento para especificar el acento.
Creo que es más seguro especificar explícitamente qué diactrics desea eliminar:
fuente