Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

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 caracteres no diacríticos?

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

¿Fue útil?

Solución

Copiando de 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, " & # 225; " se reemplazará por " ; a '' seguido de un acento agudo combinado). Luego 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 detectar aún más casos.

     

Referencias:

     

Otros consejos

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 
    //   (e.g. 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 necesitar 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 comun. Sus opciones son básicamente: eliminar los caracteres acentuados o intentar eliminar los acentos de los caracteres acentuados para intentar preservar todo lo que pueda de la entrada original. Obviamente, esta no es una solución perfecta, pero es un 80% mejor que simplemente eliminar cualquier carácter por encima de ASCII 127.

También podría valer la pena retroceder y considerar por qué quiere hacer esto. Si está tratando de eliminar las diferencias de caracteres que considera insignificantes, debe mirar el algoritmo de intercalación Unicode. Esta es la forma estándar de ignorar diferencias como mayúsculas o minúsculas al comparar cadenas para buscar u ordenar.

Si planea mostrar el texto modificado, considere a su audiencia. Lo que puede filtrar con seguridad es la configuración regional. En inglés de EE. UU., "Iglú" = " iglú " ;, y " reanudar " = " r & # 233; sum & # 233; " ;, pero en turco, una minúscula I es & # 305; (sin puntos), y en francés, cote significa cita, c & # 244; t & # 233; significa lado, y c & # 244; te significa costa. Entonces, el lenguaje de clasificació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 utilizando la descomposición Unicode. Con esto, puede descomponer un personaje 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 personaje de combinación, y debería tener el "no diacrítico" unos.

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

Para un ejemplo simple:

Para eliminar diacríticos de una cadena:

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

Mi sitio ingresa datos de fuentes externas que tienen muchos caracteres extraños. Escribí la siguiente función de C # para reemplazar los caracteres acentuados y eliminar los caracteres del teclado que no son de EE. UU. Usando 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 que ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top