Eliminar acentos y diacríticos de un String en Java
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