Todos nos hemos encontrado en la situación de tener que eliminar las tildes y diacrípticos de una cadena de texto o String en una aplicación Java. Los motivos por los que hacemos esto pueden ser muy diversos:
- para realizar algún tipo de comparación entre cadenas de texto
- para intentar normalizar de alguna manera la cadena de texto antes de guardarlos en una base de datos
- etc
En cualquier caso el código que nos resuelve esto es muy sencillo
Código Java
package example.string; import java.text.Normalizer; public class Norm { public static void main(String[] args) throws Exception { String cadena = "áéíóú"; System.out.println(cadena + " = " + cleanString(cadena)); cadena = "àèìòù"; System.out.println(cadena + " = " + cleanString(cadena)); cadena = "äëïöü"; System.out.println(cadena + " = " + cleanString(cadena)); cadena = "âêîôû"; System.out.println(cadena + " = " + cleanString(cadena)); cadena = "2² + 2³"; System.out.println(cadena + " = " + cleanString(cadena)); } public static String cleanString(String texto) { texto = Normalizer.normalize(texto, Normalizer.Form.NFD); texto = texto.replaceAll("[\\p{InCombiningDiacriticalMarks}]", ""); return texto; } }
Resultado de la ejecución
áéíóú = aeiou àèìòù = aeiou äëïöü = aeiou âêîôû = aeiou
Normalizer.normalize(texto, Normalizer.Form.NFD);
Según el API de la Jdk los métodos normalize de java.text.Normalizer transforman un texto Unicode en su representación compuesta o descompuesta, lo que nos permite poder buscar y ordenar textos de una forma más sencilla después de la transformación.
La transformación está recogida en un estándar de Unicode que lo podemos consultar en Unicode Standard Annex #15 Unicode Normalization Forms.
De este estándar nos interesa la transformación llamada Canonical decomposition.
Esta transformación transforma los caracteres con tildes y diacríticos separandolos en dos caracteres. Por ejemplo
á = a´ ä = a¨ â = a^
y con lo que el código
Normalizer.normalize(texto, Normalizer.Form.NFD);
convertimos los textos a su forma Canonical decomposition que utilizaremos en el siguiente paso para lograr nuestro objetivo.
\p{InCombiningDiacriticalMarks}
Lo utilizamos en expresiones regulares, y es independiente del lenguaje, por lo que lo podemos utilizar desde Java, Javascript, Php, Perl, Node.js y todo aquel lenguaje con una implementación básica de expresiones regulares.
Esta expresión representa los caracteres UTF-8 comprendidos entre
- U+0300 hasta U+036F
entre los que se encuentran las tildes y todos los diacríticos en los que estamos interesados.
Entonces el código
texto = texto.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
lo que hace es eliminar todos esos caracteres del texto, consiguiendo finalmente el resultado esperado.
Tabla con los caracteres comprendidos entre U+0300 y U+036F
U+0300 ̀ ̀ ̀ ̀ ̀ COMBINING GRAVE ACCENT U+0301 ́ ́ ́ ́ ́ COMBINING ACUTE ACCENT U+0302 ̂ ̂ ̂ ̂ ̂ COMBINING CIRCUMFLEX ACCENT U+0303 ̃ ̃ ̃ ̃ ̃ COMBINING TILDE U+0304 ̄ ̄ ̄ ̄ ̄ COMBINING MACRON U+0305 ̅ ̅ ̅ ̅ ̅ COMBINING OVERLINE U+0306 ̆ ̆ ̆ ̆ ̆ COMBINING BREVE U+0307 ̇ ̇ ̇ ̇ ̇ COMBINING DOT ABOVE U+0308 ̈ ̈ ̈ ̈ ̈ COMBINING DIAERESIS U+0309 ̉ ̉ ̉ ̉ ̉ COMBINING HOOK ABOVE U+030A ̊ ̊ ̊ ̊ ̊ COMBINING RING ABOVE U+030B ̋ ̋ ̋ ̋ ̋ COMBINING DOUBLE ACUTE ACCENT U+030C ̌ ̌ ̌ ̌ ̌ COMBINING CARON U+030D ̍ ̍ ̍ ̍ ̍ COMBINING VERTICAL LINE ABOVE U+030E ̎ ̎ ̎ ̎ ̎ COMBINING DOUBLE VERTICAL LINE ABOVE U+030F ̏ ̏ ̏ ̏ ̏ COMBINING DOUBLE GRAVE ACCENT U+0310 ̐ ̐ ̐ ̐ ̐ COMBINING CANDRABINDU U+0311 ̑ ̑ ̑ ̑ ̑ COMBINING INVERTED BREVE U+0312 ̒ ̒ ̒ ̒ ̒ COMBINING TURNED COMMA ABOVE U+0313 ̓ ̓ ̓ ̓ ̓ COMBINING COMMA ABOVE U+0314 ̔ ̔ ̔ ̔ ̔ COMBINING REVERSED COMMA ABOVE U+0315 ̕ ̕ ̕ ̕ ̕ COMBINING COMMA ABOVE RIGHT U+0316 ̖ ̖ ̖ ̖ ̖ COMBINING GRAVE ACCENT BELOW U+0317 ̗ ̗ ̗ ̗ ̗ COMBINING ACUTE ACCENT BELOW U+0318 ̘ ̘ ̘ ̘ ̘ COMBINING LEFT TACK BELOW U+0319 ̙ ̙ ̙ ̙ ̙ COMBINING RIGHT TACK BELOW U+031A ̚ ̚ ̚ ̚ ̚ COMBINING LEFT ANGLE ABOVE U+031B ̛ ̛ ̛ ̛ ̛ COMBINING HORN U+031C ̜ ̜ ̜ ̜ ̜ COMBINING LEFT HALF RING BELOW U+031D ̝ ̝ ̝ ̝ ̝ COMBINING UP TACK BELOW U+031E ̞ ̞ ̞ ̞ ̞ COMBINING DOWN TACK BELOW U+031F ̟ ̟ ̟ ̟ ̟ COMBINING PLUS SIGN BELOW U+0320 ̠ ̠ ̠ ̠ ̠ COMBINING MINUS SIGN BELOW U+0321 ̡ ̡ ̡ ̡ ̡ COMBINING PALATALIZED HOOK BELOW U+0322 ̢ ̢ ̢ ̢ ̢ COMBINING RETROFLEX HOOK BELOW U+0323 ̣ ̣ ̣ ̣ ̣ COMBINING DOT BELOW U+0324 ̤ ̤ ̤ ̤ ̤ COMBINING DIAERESIS BELOW U+0325 ̥ ̥ ̥ ̥ ̥ COMBINING RING BELOW U+0326 ̦ ̦ ̦ ̦ ̦ COMBINING COMMA BELOW U+0327 ̧ ̧ ̧ ̧ ̧ COMBINING CEDILLA U+0328 ̨ ̨ ̨ ̨ ̨ COMBINING OGONEK U+0329 ̩ ̩ ̩ ̩ ̩ COMBINING VERTICAL LINE BELOW U+032A ̪ ̪ ̪ ̪ ̪ COMBINING BRIDGE BELOW U+032B ̫ ̫ ̫ ̫ ̫ COMBINING INVERTED DOUBLE ARCH BELOW U+032C ̬ ̬ ̬ ̬ ̬ COMBINING CARON BELOW U+032D ̭ ̭ ̭ ̭ ̭ COMBINING CIRCUMFLEX ACCENT BELOW U+032E ̮ ̮ ̮ ̮ ̮ COMBINING BREVE BELOW U+032F ̯ ̯ ̯ ̯ ̯ COMBINING INVERTED BREVE BELOW U+0330 ̰ ̰ ̰ ̰ ̰ COMBINING TILDE BELOW U+0331 ̱ ̱ ̱ ̱ ̱ COMBINING MACRON BELOW U+0332 ̲ ̲ ̲ ̲ ̲ COMBINING LOW LINE U+0333 ̳ ̳ ̳ ̳ ̳ COMBINING DOUBLE LOW LINE U+0334 ̴ ̴ ̴ ̴ ̴ COMBINING TILDE OVERLAY U+0335 ̵ ̵ ̵ ̵ ̵ COMBINING SHORT STROKE OVERLAY U+0336 ̶ ̶ ̶ ̶ ̶ COMBINING LONG STROKE OVERLAY U+0337 ̷ ̷ ̷ ̷ ̷ COMBINING SHORT SOLIDUS OVERLAY U+0338 ̸ ̸ ̸ ̸ ̸ COMBINING LONG SOLIDUS OVERLAY U+0339 ̹ ̹ ̹ ̹ ̹ COMBINING RIGHT HALF RING BELOW U+033A ̺ ̺ ̺ ̺ ̺ COMBINING INVERTED BRIDGE BELOW U+033B ̻ ̻ ̻ ̻ ̻ COMBINING SQUARE BELOW U+033C ̼ ̼ ̼ ̼ ̼ COMBINING SEAGULL BELOW U+033D ̽ ̽ ̽ ̽ ̽ COMBINING X ABOVE U+033E ̾ ̾ ̾ ̾ ̾ COMBINING VERTICAL TILDE U+033F ̿ ̿ ̿ ̿ ̿ COMBINING DOUBLE OVERLINE U+0340 ̀ ̀ ̀ ̀ ̀ COMBINING GRAVE TONE MARK U+0341 ́ ́ ́ ́ ́ COMBINING ACUTE TONE MARK U+0342 ͂ ͂ ͂ ͂ ͂ COMBINING GREEK PERISPOMENI U+0343 ̓ ̓ ̓ ̓ ̓ COMBINING GREEK KORONIS U+0344 ̈́ ̈́ ̈́ ̈́ ̈́ COMBINING GREEK DIALYTIKA TONOS U+0345 ͅ ͅ ͅ ͅ ͅ COMBINING GREEK YPOGEGRAMMENI U+0346 ͆ ͆ ͆ ͆ ͆ COMBINING BRIDGE ABOVE U+0347 ͇ ͇ ͇ ͇ ͇ COMBINING EQUALS SIGN BELOW U+0348 ͈ ͈ ͈ ͈ ͈ COMBINING DOUBLE VERTICAL LINE BELOW U+0349 ͉ ͉ ͉ ͉ ͉ COMBINING LEFT ANGLE BELOW U+034A ͊ ͊ ͊ ͊ ͊ COMBINING NOT TILDE ABOVE U+034B ͋ ͋ ͋ ͋ ͋ COMBINING HOMOTHETIC ABOVE U+034C ͌ ͌ ͌ ͌ ͌ COMBINING ALMOST EQUAL TO ABOVE U+034D ͍ ͍ ͍ ͍ ͍ COMBINING LEFT RIGHT ARROW BELOW U+034E ͎ ͎ ͎ ͎ ͎ COMBINING UPWARDS ARROW BELOW U+034F ͏ ͏ ͏ ͏ ͏ COMBINING GRAPHEME JOINER U+0350 ͐ ͐ ͐ ͐ ͐ COMBINING RIGHT ARROWHEAD ABOVE U+0351 ͑ ͑ ͑ ͑ ͑ COMBINING LEFT HALF RING ABOVE U+0352 ͒ ͒ ͒ ͒ ͒ COMBINING FERMATA U+0353 ͓ ͓ ͓ ͓ ͓ COMBINING X BELOW U+0354 ͔ ͔ ͔ ͔ ͔ COMBINING LEFT ARROWHEAD BELOW U+0355 ͕ ͕ ͕ ͕ ͕ COMBINING RIGHT ARROWHEAD BELOW U+0356 ͖ ͖ ͖ ͖ ͖ COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW U+0357 ͗ ͗ ͗ ͗ ͗ COMBINING RIGHT HALF RING ABOVE U+0358 ͘ ͘ ͘ ͘ ͘ COMBINING DOT ABOVE RIGHT U+0359 ͙ ͙ ͙ ͙ ͙ COMBINING ASTERISK BELOW U+035A ͚ ͚ ͚ ͚ ͚ COMBINING DOUBLE RING BELOW U+035B ͛ ͛ ͛ ͛ ͛ COMBINING ZIGZAG ABOVE U+035C ͜ ͜ ͜ ͜ ͜ COMBINING DOUBLE BREVE BELOW U+035D ͝ ͝ ͝ ͝ ͝ COMBINING DOUBLE BREVE U+035E ͞ ͞ ͞ ͞ ͞ COMBINING DOUBLE MACRON U+035F ͟ ͟ ͟ ͟ ͟ COMBINING DOUBLE MACRON BELOW U+0360 ͠ ͠ ͠ ͠ ͠ COMBINING DOUBLE TILDE U+0361 ͡ ͡ ͡ ͡ ͡ COMBINING DOUBLE INVERTED BREVE U+0362 ͢ ͢ ͢ ͢ ͢ COMBINING DOUBLE RIGHTWARDS ARROW BELOW U+0363 ͣ ͣ ͣ ͣ ͣ COMBINING LATIN SMALL LETTER A U+0364 ͤ ͤ ͤ ͤ ͤ COMBINING LATIN SMALL LETTER E U+0365 ͥ ͥ ͥ ͥ ͥ COMBINING LATIN SMALL LETTER I U+0366 ͦ ͦ ͦ ͦ ͦ COMBINING LATIN SMALL LETTER O U+0367 ͧ ͧ ͧ ͧ ͧ COMBINING LATIN SMALL LETTER U U+0368 ͨ ͨ ͨ ͨ ͨ COMBINING LATIN SMALL LETTER C U+0369 ͩ ͩ ͩ ͩ ͩ COMBINING LATIN SMALL LETTER D U+036A ͪ ͪ ͪ ͪ ͪ COMBINING LATIN SMALL LETTER H U+036B ͫ ͫ ͫ ͫ ͫ COMBINING LATIN SMALL LETTER M U+036C ͬ ͬ ͬ ͬ ͬ COMBINING LATIN SMALL LETTER R U+036D ͭ ͭ ͭ ͭ ͭ COMBINING LATIN SMALL LETTER T U+036E ͮ ͮ ͮ ͮ ͮ COMBINING LATIN SMALL LETTER V U+036F ͯ ͯ ͯ ͯ ͯ COMBINING LATIN SMALL LETTER X