Normalizando Unicode

¿Existe una forma estándar, en Python, para normalizar una cadena Unicode, de modo que solo comprenda las entidades Unicode más simples que se pueden usar para representarla?

Quiero decir, ¿algo que traduciría una secuencia como ['LATIN SMALL LETTER A', 'COMBINING ACUTE ACCENT'] a ['LATIN SMALL LETTER A WITH ACUTE'] ?

Vea dónde está el problema:

 >>> import unicodedata >>> char = "á" >>> len(char) 1 >>> [ unicodedata.name(c) for c in char ] ['LATIN SMALL LETTER A WITH ACUTE'] 

Pero ahora:

 >>> char = "á" >>> len(char) 2 >>> [ unicodedata.name(c) for c in char ] ['LATIN SMALL LETTER A', 'COMBINING ACUTE ACCENT'] 

Podría, por supuesto, iterar sobre todos los caracteres y hacer reemplazos manuales, etc., pero no es eficiente, y estoy bastante seguro de que me perdería la mitad de los casos especiales y cometería errores.

El módulo unicodedata ofrece una función .normalize() , que desea normalizar a la forma NFC:

 >>> unicodedata.normalize('NFC', u'\u0061\u0301') u'\xe1' >>> unicodedata.normalize('NFD', u'\u00e1') u'a\u0301' 

NFC, o ‘Forma normal compuesta’ devuelve los caracteres compuestos, NFD, ‘Forma normal descompuesta’ te da caracteres descompuestos combinados.

Los formularios NFKC y NFKD adicionales tratan con puntos de código de compatibilidad; Por ejemplo, U + 2160 (ROMAN NUMERAL ONE) es exactamente lo mismo que U + 0049 (LATIN CAPITAL LETTER I) pero está presente en el estándar de Unicode para seguir siendo compatible con las codificaciones que los tratan por separado. El uso de formularios NFKC o NFKD, además de componer o descomponer caracteres, también reemplazará todos los caracteres de “compatibilidad” con su forma canónica:

 >>> unicodedata.normalize('NFC', u'\u2167') # roman numeral VIII u'\u2167' >>> unicodedata.normalize('NFKC', u'\u2167') # roman numeral VIII u'VIII' 

Tenga en cuenta que no hay garantía de que las formas compuestas y descompuestas sean comunicativas; la normalización de un carácter combinado a la forma NFC, y luego la conversión del resultado a la forma NFD no siempre resulta en la misma secuencia de caracteres. El estándar Unicode mantiene una lista de excepciones ; Los personajes en esta lista son compositivos, pero no pueden descomponerse de nuevo a su forma combinada, por varias razones. También vea la documentación en la Tabla de Exclusión de Composición .

Si, hay

 unicodedata.normalize(form, unistr) 

Debe seleccionar uno de los cuatro formularios de normalización .