2008-12-01 9 views
13

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?Cómo cambiar los caracteres diacríticos a los que no son diacríticos

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

+0

Cuando tuve que hacer esto en Perl, solo tuve una gran afirmación "tr" mantenida a mano, así que buena suerte. –

+0

esto es un duplicado de _several_ preguntas. buscar "translit", por ejemplo. por favor no maquines nuestros idiomas! – hop

Respuesta

10

Copia desde my own answer to another question:

En lugar de crear su propia mesa, en su lugar podría convertir el texto en forma de normalización D, donde los personajes se representan como un personaje base más los signos diacríticos (por ejemplo, "á" se reemplazará por "a" seguido de un acento agudo que combine). A continuación, puede quitar todo lo que no sea una letra ASCII.

Las tablas aún 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:

+8

por favor no haga esto, si es posible. estás matando nuestros idiomas. intente usar la transliteración – hop

+0

@hop, hay muchas razones válidas para hacer esto (generar n-gramas normalizados para el análisis léxico, por ejemplo) – Diadistis

+0

@Diadistis: a) no creo que la transliteración adecuada dificulte ese tipo de análisis yb) " muchas razones válidas "? nombrar unos pocos ... – hop

4

También valdría la pena dar un paso atrás y considerar qué que quieren 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 va a mostrar el texto modificado, tenga en cuenta su 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 diacritics es la solución correcta 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 automatizado usando la descomposición 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.

+2

Creo que uno de los usos de esto es crear buenas URL –

+0

Absolutamente. Si tiene un producto llamado "Rändi Fay_Female Vocalist" y necesita generar un stub/producto/algo de url, sus opciones son esencialmente reemplazar el acentuado a con uno sin acentos, o con URL, escapa de la cadena dejando un feo porcentaje allí. El a sin acentos es mucho más preferible. Las URL son cadenas legibles por máquina, pero a menudo es importante que sean al menos semi-legibles por humanos. –

1

Para un ejemplo simple:

Para eliminar los signos diacríticos de una cadena:

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

no trabajo: "ě" .Normalize (NormalizationForm.FormD) no devuelve "e" – Feryt

+0

Sí, sí, use String.ToCharArray() para verlo –

+0

Al igual que Feryt, no funciona para mí. ("xxé"). Normalize (NormalizationForm.FormD) devuelve "xxe" (como se esperaba), pero string v = "xxé"; v.Normalizar (NormalizationForm.FormD); devuelve "xxé". He intentado llamar a v.ToCharArray() y ("xxé"). ToCharArray() para ver si hay alguna diferencia, devuelven la misma matriz. Muy extraño ! – AFract

27

Ya que 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 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 carácter anterior ascii 127.

0

Mi sitio ingresa datos de fuentes externas que tienen muchos caracteres extraños. Escribí la siguiente función en C# para reemplazar los caracteres acentuados y tira a los caracteres del teclado no estadounidenses usando expresiones regulares:

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 \.,\?'""[email protected]#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*", string.Empty).Trim();  
    } 

espero que ayude.

Cuestiones relacionadas