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 se verán atrapadas por este, 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<char> RemoveDiacriticsEnum(string src, bool compatNorm, Func<char, char> 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<char> RemoveDiacriticsEnum(string src, bool compatNorm)
{
return RemoveDiacritics(src, compatNorm, c => c);
}
public static string RemoveDiacritics(string src, bool compatNorm, Func<char, char> 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í hay un valor predeterminado para los casos problemáticos 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 caso de ejemplo de algo donde queríamos convertir también L y L a L y L, pero no tenía otras preocupaciones especializadas podrían utilizar:
private static char NormaliseLWithStroke(char c)
{
switch(c)
{
case 'ł':
return 'l';
case 'Ł':
return 'L';
default:
return c;
}
}
El uso de este con los métodos anteriores se combinan para eliminar el accidente cerebrovascular en este caso, junto con los signos diagonales descomponibles.
Maldición, quiero rescindir mi reapertura, definitivamente es un duplicado. @BrunoLM si no te gusta la respuesta, es mejor ponerle una recompensa que pedir a un duplicado –