Cómo cambiar los caracteres diacríticos a los que no son diacríticos

He encontrado una respuesta sobre cómo eliminar caracteres diacríticos en stackoverflow, pero ¿podría decirme si es posible cambiar los caracteres diacríticos por otros no diacríticos?

Oh … y pienso en .NET (u otro si no es posible)

Copiando mi propia respuesta a otra pregunta :

En lugar de crear su propia tabla, podría convertir el texto a la forma de normalización D, donde los caracteres se representan como un carácter base más los signos diacríticos (por ejemplo, “á” será reemplazado por “a” seguido de un acento agudo que combina ) A continuación, puede quitar todo lo que no sea una letra ASCII.

Las tablas todavía existen, pero ahora son las del estándar Unicode.

También puede probar NFKD en lugar de NFD, para atrapar aún más casos.

Referencias

Como nadie se ha molestado en publicar el código para hacer esto, aquí está:

// \p{Mn} or \p{Non_Spacing_Mark}: // a character intended to be combined with another // character without taking up extra space // (eg accents, umlauts, etc.). private readonly static Regex nonSpacingMarkRegex = new Regex(@"\p{Mn}", RegexOptions.Compiled); public static string RemoveDiacritics(string text) { if (text == null) return string.Empty; var normalizedText = text.Normalize(NormalizationForm.FormD); return nonSpacingMarkRegex.Replace(normalizedText, string.Empty); } 

Nota: una gran razón para tener que hacer esto es cuando se está integrando a un sistema de terceros que solo hace ascii, pero sus datos están en unicode. Esto es común. Sus opciones son básicamente: eliminar los caracteres acentuados o intentar eliminar los acentos de los caracteres acentuados para intentar preservar tanto como sea posible de la entrada original. Obviamente, esta no es una solución perfecta, pero es un 80% mejor que simplemente eliminar cualquier personaje arriba ascii 127.

También podría valer la pena dar un paso atrás y considerar por qué quieres hacer esto. Si intenta eliminar las diferencias de caracteres que considera insignificantes, debe ver el algoritmo de intercalación Unicode. Esta es la forma estándar de ignorar las diferencias, como mayúsculas o minúsculas, al comparar cadenas para buscar o clasificar.

Si planeas mostrar el texto modificado, considera a tu público. Lo que puede filtrar con seguridad es sensible a la configuración regional. En inglés de EE. UU., “Igloo” = “igloo” y “resume” = “currículum”, pero en turco, una minúscula I es ı (sin punto) y en francés, cote significa citar, côté significa “lado” y “côte” significa costa. Entonces, el lenguaje de colación determina qué diferencias son significativas.

Si eliminar diacríticos es la solución adecuada para su aplicación, es más seguro producir su propia tabla a la que agregue explícitamente los caracteres que desea convertir.

Se podría idear un enfoque general y automatizado usando la descomposición de Unicode. Con esto, puede descomponer un carácter con signos diacríticos para “combinar” caracteres (las marcas diacríticas) y el carácter base con el que se combinan. Filtre cualquier cosa que sea un carácter de combinación, y debería tener los que no son diacríticos.

La falta de discriminación en el método automático, sin embargo, podría tener algunos efectos inesperados. Recomendaría muchas pruebas en un cuerpo representativo de texto.

Para un simple ejemplo:

Para eliminar signos diacríticos de una cadena:

 string newString = myDiacriticsString.Normalize(NormalizationForm.FormD); 

Mi sitio ingresa datos de fonts externas que tienen muchos caracteres extraños. Escribí la siguiente función C # para reemplazar caracteres acentuados y eliminar caracteres de teclado que no sean de EE. UU. Utilizando Regex:

  using System.Text; using System.Text.RegularExpressions; internal static string SanitizeString(string source) { return Regex.Replace(source.Normalize(NormalizationForm.FormD), @"[^A-Za-z 0-9 \.,\?'""!@#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*", string.Empty).Trim(); } 

Espero eso ayude.