Sadot Hernández

Normalizando Texto con la API Normalizer

PublicadoMarch 20, 2021

Eliminar acentos y diacríticos de un String en Java

image

Normalizando Texto con la API Normalizer

La normalización es un proceso mediante el cual se pueden realizar ciertas transformaciones de texto para hacerlo reconciliable de una manera que puede que no haya sido antes. Digamos que te gustaría buscar u ordenar texto; en este caso, necesita normalizar ese texto para tener en cuenta los puntos de código que deben representarse como el mismo texto.

¿Qué se puede normalizar? 

La normalización es aplicable cuando necesita convertir caracteres con marcas diacríticas, cambiar todas las letras entre mayúsculas y minúsculas, descomponer ligaduras o convertir caracteres katakana de ancho medio en caracteres de ancho completo, etc.

De acuerdo con el Anexo # 15 del Estándar Unicode, la API Normalizer admite las siguientes cuatro formas de normalización de texto Unicode que se definen en java.text.Normalizer.Form:

Forma de normalización D (NFD): Descomposición canónica

Forma de normalización C (NFC): Descomposición canónica, seguida de Composición canónica

Forma de normalización KD (NFKD): Descomposición de compatibilidad

Forma de normalización KC (NFKC): Descomposición de compatibilidad, seguida de Composición canónica

Examinemos cómo la letra minúscula latina "ö" con diéresis se puede normalizar utilizando estas formas de normalización:

 

Palabra original

NFC

NFD

NFKC

NFKD

"schön"

"schön"

"scho \ u0308n"

"schön"

"scho \ u0308n"

 

Se puede notar que la palabra original se deja sin cambios en NFC y NFKC. Esto se debe a que con NFD y NFKD, los caracteres compuestos se asignan a sus descomposiciones canónicas. Pero con NFC y NFKC, la combinación de secuencias de caracteres se asigna a compuestos, si es posible. No hay composite para la diéresis (ö), por lo que se deja descompuesto en NFC y NFKC.

En el ejemplo de código, que se representa más adelante, también se puede observar otra característica de normalización. Los caracteres katakana de ancho medio y ancho completo tendrán la misma descomposición de compatibilidad y, por lo tanto, son equivalentes de compatibilidad. Sin embargo, no son equivalentes canónicos.

Para asegurarse de que realmente necesita normalizar el texto, se puede usar el método isNormalized para determinar si la secuencia dada de valores de caracteres está normalizada. Si este método devuelve falso, significa que se debe normalizar esta secuencia y se debe usar el método normalize que normaliza los valores de tipo carácter de acuerdo con la forma de normalización especificada. Por ejemplo, para transformar el texto a la forma descompuesta canónica, se tendrá que utilizar el método normalize:

normalized_string = Normalizer.normalize (target_chars, Normalizer.Form.NFD);

Además, el método normalize reorganiza los acentos en el orden canónico adecuado, de modo que no tenga que preocuparse por la reordenación de los acentos por su cuenta.

En el siguiente ejemplo se representa una aplicación en la cual se desea quitar los acentos y diacríticos de un String.

import java.text.Normalizer;

public class NormalizerWord{

     public static void main(String[] args) throws Exception {
        
        //Textos
        String textoUno = "ö ä ñ á";
        String textoUnoNFD = "";


        String textoDos = "Ö Ä Ñ Á";
        String textoDosNFD = "";
       
        //Se normaliza el textoUno
        textoUno = Normalizer.normalize(textoUno, Normalizer.Form.NFD);
        textoUnoNFD = textoUno.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
       
        //Se normaliza el textoDos
        textoDos = Normalizer.normalize(textoDos, Normalizer.Form.NFD);
        textoDosNFD = textoDos.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
       
       
        System.out.println("Texto Uno: " + textoUno + " = " + textoUnoNFD);
        System.out.println("Texto Dos: " + textoDos + " = " + textoDosNFD);
    
    }

}

Output:

Texto Uno: ö ä ñ á = o a n a
Texto Dos: Ö Ä Ñ Á = O A N A

También hay que tener en cuenta la codificación UTF-8 y ISO-8859-1 al momento de utilizar el método normalize.

Referencias

Oracle. (2020). Docs Oracle. Obtenido de Docs Oracle: https://docs.oracle.com/javase/tutorial/i18n/text/normalizerapi.html