¿Cómo puedo eliminar acentos en una cadena?

Posible duplicado:
¿Cómo elimino diacríticos (acentos) de una cadena en .NET?

Tengo la siguiente cadena

áéíóú 

que necesito convertirlo a

 aeiou 

¿Cómo puedo lograrlo? (No necesito comparar, necesito la nueva cadena para guardar)


No es un duplicado de ¿Cómo elimino los signos diacríticos (acentos) de una cadena en .NET? . La respuesta aceptada allí no explica nada y es por eso que la he “reabierto”.

Depende de los requisitos. Para la mayoría de los usos, entonces normalizar a NFD y luego filtrar todos los caracteres combinados funcionará. En algunos casos, la normalización a NFKD es más apropiada (si también desea eliminar algunas distinciones adicionales entre caracteres).

Algunas otras distinciones no serán captadas por esto, especialmente los caracteres latinos acariciados. Tampoco hay una forma clara y específica para algunos (¿se debe considerar que es equivalente a l o w?), Por lo que es posible que deba personalizarla más allá de esto.

También hay algunos casos en los que NFD y NFKD no funcionan del modo esperado, para permitir la coherencia entre las versiones de Unicode.

Por lo tanto:

 public static IEnumerable RemoveDiacriticsEnum(string src, bool compatNorm, Func customFolding) { foreach(char c in src.Normalize(compatNorm ? NormalizationForm.FormKD : NormalizationForm.FormD)) switch(CharUnicodeInfo.GetUnicodeCategory(c)) { case UnicodeCategory.NonSpacingMark: case UnicodeCategory.SpacingCombiningMark: case UnicodeCategory.EnclosingMark: //do nothing break; default: yield return customFolding(c); break; } } public static IEnumerable RemoveDiacriticsEnum(string src, bool compatNorm) { return RemoveDiacritics(src, compatNorm, c => c); } public static string RemoveDiacritics(string src, bool compatNorm, Func customFolding) { StringBuilder sb = new StringBuilder(); foreach(char c in RemoveDiacriticsEnum(src, compatNorm, customFolding)) sb.Append(c); return sb.ToString(); } public static string RemoveDiacritics(string src, bool compatNorm) { return RemoveDiacritics(src, compatNorm, c => c); } 

Aquí tenemos un valor predeterminado para los casos de problema mencionados anteriormente, que simplemente los ignora. También hemos dividido construir una cadena para que no se genere la enumeración de caracteres, por lo que no debemos desperdiciar en los casos donde no hay necesidad de manipulación de cadenas en el resultado (digamos que íbamos a escribir los caracteres a la salida siguiente, o hacer un char adicional manipulación por charla).

Un ejemplo de caso para algo en el que también queríamos convertir ³ y Ł a ly l, pero no tenía otras preocupaciones especializadas podría utilizar:

 private static char NormaliseLWithStroke(char c) { switch(c) { case 'ł': return 'l'; case 'Ł': return 'L'; default: return c; } } 

Usar esto con los métodos anteriores se combinará para eliminar el trazo en este caso, junto con los signos diagonales descomponibles.

 public string RemoveDiacritics(string input) { string stFormD = input.Normalize(NormalizationForm.FormD); int len = stFormD.Length; StringBuilder sb = new StringBuilder(); for (int i = 0; i < len; i++) { System.Globalization.UnicodeCategory uc = System.Globalization.CharUnicodeInfo.GetUnicodeCategory(stFormD[i]); if (uc != System.Globalization.UnicodeCategory.NonSpacingMark) { sb.Append(stFormD[i]); } } return (sb.ToString().Normalize(NormalizationForm.FormC)); }