[Python-es] Comparación de cadenas no sensible a acentos

Ricardo Cárdenes Medina ricardo.cardenes en gmail.com
Vie Dic 10 01:42:48 CET 2010


2010/12/9 Luis Miguel Morillas <morillas en gmail.com>
>
> Cómo hacemos esto en python? Quiero que se compare como similar
> 'tecnica' y 'técnica' por ejemplo.

Asumiendo que estés trabajando con cadenas unicode, puedes usar el
módulo unicodedata para esto. La base del método está en que Unicode
define varias "formas normales" para una cadena Unicode. Ejemplo

  >>> cad = u'técnica'
  >>> unicodedata.normalize('NFC', cad)
  u't\xe9cnica'
  >>> unicodedata.normalize('NFD', cad)
  u'te\u0301cnica'

Fíjate que la forma normal C (NFC) es a la que estamos habituados,
donde la é es un único caracter. Sin embargo, existe una forma normal
D - descompuesta -, en la que cada caracter queda definido por su
descomposición en otros elementos. En este caso, e+diacrítico.

Además, cada caracter tiene una categoría:

  >>> unicodedata.category(u'e')
  'Ll'
  >>> unicodedata.category(u"\u0301")
  'Mn'

Sabiendo esto, podríamos crear una función tal que...

   def normaliza(cadena):
      from unicodedata import normalize, category
      return ''.join([x for x in normalize('NFD', u) if category(x) == 'Ll'])


   >>> normaliza(u'tecnica') == normaliza(u'técnica')
   True

El método vale para todas las letras acentuadas y además convierte
eñes en enes, cedillas en ces, etc.


Más información sobre la lista de distribución Python-es