utf8 example .net unicode ascii codepages normalize

.net - utf8 - encoding c# example



¿Puede.NET convertir Unicode a ASCII para eliminar "citas inteligentes", etc.? (4)

Tuve algunos problemas con esto, al usar una lista de cadenas originalmente construidas en Word. Descubrí que el uso de un "String".replace(current char/string, new char/string) simple "String".replace(current char/string, new char/string) funciona perfectamente. El código exacto que utilicé fue para citas inteligentes, o para ser exactos: izquierda ", derecha", izquierda "y derecha" es la siguiente:

StringName = StringName.Replace(ChrW(8216), "''") '' Replaces any left '' with a normal '' StringName = StringName.Replace(ChrW(8217), "''") '' Replaces any right '' with a normal '' StringName = StringName.Replace(ChrW(8220), """") '' Replace any left " with a normal " StringName = StringName.Replace(ChrW(8221), """") '' Replace any right " with a normal "

¡Espero que esto ayude a cualquier persona que todavía tenga este problema!

Algunos de nuestros usuarios utilizan clientes de correo electrónico que no pueden hacer frente a Unicode, incluso cuando la codificación, etc. está configurada correctamente en los encabezados de correo.

Me gustaría ''normalizar'' el contenido que están recibiendo. El mayor problema que tenemos es que los usuarios copien el contenido de Microsoft Word en nuestra aplicación web, que luego reenvía ese contenido por correo electrónico, incluidas fracciones, comillas inteligentes y todos los demás caracteres Unicode extendidos que Word inserta de manera útil para usted. .

Supongo que no hay una solución definitiva para esto, pero antes de sentarme a escribir grandes tablas de búsqueda, ¿hay algún método incorporado que me permita comenzar?

Básicamente hay tres fases involucradas.

Primero, despojar acentos de letras que de otro modo serían normales, la solución a esto está aquí

This paragraph contains “smart quotes” and áccénts and ½ of the problem is fractions

va a

This paragraph contains “smart quotes” and accents and ½ of the problem is fractions

En segundo lugar, reemplazando los caracteres únicos Unicode con su equivalente ASCII, para dar:

This paragraph contains "smart quotes" and accents and ½ of the problem is fractions

Esta es la parte en la que espero que haya una solución antes de implementar la mía. Finalmente, el reemplazo de caracteres específicos con una secuencia ASCII adecuada - 1/2 a 1/2, y así sucesivamente - que estoy bastante seguro no es compatible nativamente con ningún tipo de magia Unicode, pero alguien podría haber escrito una tabla de búsqueda adecuada que pueda reutilizar.

¿Algunas ideas?


Nunca intentes convertir Unicode en ASCII porque terminarás teniendo más problemas que resolviendo.

Es como tratar de acomodar 1,114,112 puntos de código (Unicode 6.0) en solo 128 caracteres.

¿Crees que tendrás éxito?

Por cierto, hay muchas citas en Unicode, no solo las mencionadas por usted y también si desea realizar la conversión de todos modos, recuerde que las conversiones dependerán de la configuración regional.

Compruebe la ICU , que contiene las rutinas de conversión Unicode más completas.


Gracias a todos por algunas respuestas muy útiles. Me doy cuenta de que la pregunta real no es "¿Cómo puedo convertir CUALQUIER carácter Unicode en su versión ASCII?": La pregunta es "¿cómo puedo convertir los caracteres Unicode de los que se quejan mis clientes en sus inconvenientes ASCII"?

En otras palabras, no necesitamos una solución de propósito general; necesitamos una solución que funcione el 99% del tiempo, para clientes de habla inglesa que peguen contenido en inglés de Word y otros sitios web en nuestra aplicación. Con ese fin, analicé el valor de ocho años de mensajes enviados a través de nuestro sistema buscando caracteres que no son representables en codificación ASCII, usando esta prueba:

///<summary>Determine whether the supplied character is ///using ASCII encoding.</summary> bool IsAscii(char inputChar) { var ascii = new ASCIIEncoding(); var asciiChar = (char)(ascii.GetBytes(inputChar.ToString())[0]); return(asciiChar == inputChar); }

Luego revisé el conjunto resultante de caracteres irrepresentables y asigné manualmente una cadena de reemplazo apropiada. Todo el lote se incluye en un método de extensión, por lo que puede llamar a myString.Asciify () para convertir su cadena en una aproximación razonable de codificación ASCII.

public static class StringExtensions { private static readonly Dictionary<char, string> Replacements = new Dictionary<char, string>(); /// <summary>Returns the specified string with characters not representable in ASCII codepage 437 converted to a suitable representative equivalent. Yes, this is lossy.</summary> /// <param name="s">A string.</param> /// <returns>The supplied string, with smart quotes, fractions, accents and punctuation marks ''normalized'' to ASCII equivalents.</returns> /// <remarks>This method is lossy. It''s a bit of a hack that we use to get clean ASCII text for sending to downlevel e-mail clients.</remarks> public static string Asciify(this string s) { return (String.Join(String.Empty, s.Select(c => Asciify(c)).ToArray())); } private static string Asciify(char x) { return Replacements.ContainsKey(x) ? (Replacements[x]) : (x.ToString()); } static StringExtensions() { Replacements[''’''] = "''"; // 75151 occurrences Replacements[''–''] = "-"; // 23018 occurrences Replacements[''‘''] = "''"; // 9783 occurrences Replacements[''”''] = "/""; // 6938 occurrences Replacements[''“''] = "/""; // 6165 occurrences Replacements[''…''] = "..."; // 5547 occurrences Replacements[''£''] = "GBP"; // 3993 occurrences Replacements[''•''] = "*"; // 2371 occurrences Replacements['' ''] = " "; // 1529 occurrences Replacements[''é''] = "e"; // 878 occurrences Replacements[''ï''] = "i"; // 328 occurrences Replacements[''´''] = "''"; // 226 occurrences Replacements[''—''] = "-"; // 133 occurrences Replacements[''·''] = "*"; // 132 occurrences Replacements[''„''] = "/""; // 102 occurrences Replacements[''€''] = "EUR"; // 95 occurrences Replacements[''®''] = "(R)"; // 91 occurrences Replacements[''¹''] = "(1)"; // 80 occurrences Replacements[''«''] = "/""; // 79 occurrences Replacements[''è''] = "e"; // 79 occurrences Replacements[''á''] = "a"; // 55 occurrences Replacements[''™''] = "TM"; // 54 occurrences Replacements[''»''] = "/""; // 52 occurrences Replacements[''ç''] = "c"; // 52 occurrences Replacements[''½''] = "1/2"; // 48 occurrences Replacements[''­''] = "-"; // 39 occurrences Replacements[''°''] = " degrees "; // 33 occurrences Replacements[''ä''] = "a"; // 33 occurrences Replacements[''É''] = "E"; // 31 occurrences Replacements[''‚''] = ","; // 31 occurrences Replacements[''ü''] = "u"; // 30 occurrences Replacements[''í''] = "i"; // 28 occurrences Replacements[''ë''] = "e"; // 26 occurrences Replacements[''ö''] = "o"; // 19 occurrences Replacements[''à''] = "a"; // 19 occurrences Replacements[''¬''] = " "; // 17 occurrences Replacements[''ó''] = "o"; // 15 occurrences Replacements[''â''] = "a"; // 13 occurrences Replacements[''ñ''] = "n"; // 13 occurrences Replacements[''ô''] = "o"; // 10 occurrences Replacements[''¨''] = ""; // 10 occurrences Replacements[''å''] = "a"; // 8 occurrences Replacements[''ã''] = "a"; // 8 occurrences Replacements[''ˆ''] = ""; // 8 occurrences Replacements[''©''] = "(c)"; // 6 occurrences Replacements[''Ä''] = "A"; // 6 occurrences Replacements[''Ï''] = "I"; // 5 occurrences Replacements[''ò''] = "o"; // 5 occurrences Replacements[''ê''] = "e"; // 5 occurrences Replacements[''î''] = "i"; // 5 occurrences Replacements[''Ü''] = "U"; // 5 occurrences Replacements[''Á''] = "A"; // 5 occurrences Replacements[''ß''] = "ss"; // 4 occurrences Replacements[''¾''] = "3/4"; // 4 occurrences Replacements[''È''] = "E"; // 4 occurrences Replacements[''¼''] = "1/4"; // 3 occurrences Replacements[''†''] = "+"; // 3 occurrences Replacements[''³''] = "''"; // 3 occurrences Replacements[''²''] = "''"; // 3 occurrences Replacements[''Ø''] = "O"; // 2 occurrences Replacements[''¸''] = ","; // 2 occurrences Replacements[''Ë''] = "E"; // 2 occurrences Replacements[''ú''] = "u"; // 2 occurrences Replacements[''Ö''] = "O"; // 2 occurrences Replacements[''û''] = "u"; // 2 occurrences Replacements[''Ú''] = "U"; // 2 occurrences Replacements[''Œ''] = "Oe"; // 2 occurrences Replacements[''º''] = "?"; // 1 occurrences Replacements[''‰''] = "0/00"; // 1 occurrences Replacements[''Å''] = "A"; // 1 occurrences Replacements[''ø''] = "o"; // 1 occurrences Replacements[''˜''] = "~"; // 1 occurrences Replacements[''æ''] = "ae"; // 1 occurrences Replacements[''ù''] = "u"; // 1 occurrences Replacements[''‹''] = "<"; // 1 occurrences Replacements[''±''] = "+/-"; // 1 occurrences } }

Tenga en cuenta que hay algunos inconvenientes bastante extraños, como este:

Replacements[''³''] = "''"; // 3 occurrences Replacements[''²''] = "''"; // 3 occurrences

Esto se debe a que uno de nuestros usuarios tiene algún programa que convierte las citas inteligentes abiertas / cerradas en ² y ³ (como: dijo ²hello³) y nadie las ha utilizado para representar la exponenciación, por lo que probablemente funcione bastante bien para nosotros, pero YMMV .


¿Hay algún método incorporado que me ayude a comenzar?

Lo primero que intentaré es convertir el texto a la forma de normalización NFKD, con el método Normalize on strings. Esta sugerencia se menciona en la respuesta a la pregunta que vinculó, pero recomiendo utilizar NFKD en lugar de NFD porque NFKD eliminará las distinciones tipográficas no deseadas (por ejemplo, NBSP → espacio, o ℂ → C).

También podría hacer reemplazos genéricos por categoría Unicode . Por ejemplo, los Pd pueden reemplazarse por - , los Nd pueden reemplazarse por el correspondiente dígito 0 - 9 , y los Mn pueden reemplazarse por el hilo vacío (para eliminar acentos).

pero alguien podría haber escrito una tabla de búsqueda adecuada que pueda volver a usar.

Podría intentar usar los datos del programa Unidecode, o CLDR .

Editar : Aquí hay una gran tabla de sustitución .