Can.NET convertir Unicode en ASCII pour supprimer "citations intelligentes", etc?

certains de nos utilisateurs utilisent des clients e-mail qui ne peuvent pas gérer Unicode, même lorsque l'encodage, etc. sont correctement définis dans les en-têtes de messages.

j'aimerais "normaliser" le contenu qu'ils reçoivent. Le plus gros problème que nous avons est les utilisateurs copiant et jetant le contenu de Microsoft Word dans notre application web, qui transmet ensuite ce contenu par e-mail - y compris fractions, citations intelligentes, et tous les autres caractères Unicode étendu que Word insère utilement pour vous.

je devine qu'il n'y a pas vraiment de solution, mais avant de m'asseoir et de commencer à écrire, grandes tables de recherche, est-il une méthode intégrée qui va me faire?

Il y a essentiellement trois phases.

D'abord, enlever les accents des lettres normales-solution à cela ici

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

va

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

deuxièmement, en remplaçant les caractères Unicode simples par leurs ASCII l'équivalent, pour donner:

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

C'est la partie où j'espère qu'il y a une solution avant d'implémenter la mienne. Enfin, remplacer des caractères spécifiques par une séquence ASCII appropriée - ½ à 1/2, et ainsi de suite - qui, je suis assez sûr n'est pas nativement soutenu par une sorte de magie Unicode, mais quelqu'un pourrait avoir écrit une table de recherche appropriée que je peux réutiliser.

des idées?

17
demandé sur Community 2011-05-28 22:34:05

4 réponses

merci à tous pour vos réponses très utiles. Je me rends compte que la vraie question n'est pas "comment puis - je convertir N'importe quel caractère Unicode dans son repli ASCII" - la question Est "Comment puis-je convertir les caractères Unicode mes clients se plaignent dans leurs retombées ASCII" ?

en d'autres termes - nous n'avons pas besoin d'une solution polyvalente; nous avons besoin d'une solution qui fonctionne 99% du temps, pour les clients anglophones qui collent du contenu de langue anglaise à partir de Word et d'autres sites web dans notre application. À cette fin, j'ai analysé huit années de messages envoyés par notre système à la recherche de caractères qui ne sont pas représentables dans l'encodage ASCII, en utilisant ce test:

///<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);
}

j'ai ensuite parcouru l'ensemble résultant de caractères non brevetables et j'ai assigné manuellement une chaîne de remplacement appropriée. Le tout est enfermé dans une méthode d'extension, de sorte que vous pouvez appeler myString.Asciify () pour convertir votre chaîne de caractères en raisonnable Approximation d'encodage 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
    }
}

Notez qu'il existe certains plutôt étrange de base - comme celui-ci:

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

c'est parce qu'un de nos utilisateurs a un programme qui convertit des citations intelligentes ouvertes/fermées en 2 et 3 (comme : il a dit 2hello3) et personne ne les a jamais utilisées pour représenter l'exponentiation, donc cela fonctionnera probablement assez bien pour nous, mais YMMV.

16
répondu Dylan Beattie 2011-05-29 09:06:48

j'ai eu quelques problèmes avec cela moi-même, tout en utilisant une liste de chaînes de caractères originellement construites dans Word. J'ai trouvé que l'utilisation d'un simple "String".replace(current char/string, new char/string) commande fonctionne parfaitement. Le code exact que j'ai utilisé était intelligente, de devis, ou pour être exact: de gauche ", "gauche" et droite " est comme suit:

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 "

j'espère que cela aidera n'importe qui là-bas ayant encore ce problème!

5
répondu Paul 2012-10-15 20:01:26

est-il une méthode intégrée qui va me faire?

la première chose que j'essaierais est de convertir le texte en NFKD formulaire de normalisation, le Normaliser méthode des cordes. Cette suggestion est mentionnée dans la réponse à la question que vous avez liée, mais je recommande D'utiliser NFKD au lieu de NFD parce que NFKD va supprimer les distinctions typographiques indésirables (par exemple, → espace, ou փ փ → c).

Vous pourriez également être en mesure de génériques remplacement par catégorie Unicode. Par exemple, les Pd peuvent être remplacés par -, les Nd peuvent être remplacés par les0 -9 chiffres, et Mn peut être remplacé par une chaîne vide (pour supprimer les accents).

mais quelqu'un aurait pu écrire table de recherche appropriée que je peux réutiliser.

vous pouvez essayer d'utiliser les données du programme Unidecode, ou CLDR.

Modifier: Il y a un énorme substitution graphique ici.

1
répondu dan04 2017-10-11 00:35:54

vous ne devriez jamais essayer de convertir Unicode en ASCII parce que vous finirez par avoir plus de problèmes que de résoudre.

c'est comme essayer d'insérer 1.114.112 codépoints (Unicode 6.0) en seulement 128 caractères.

pensez-vous réussir?

BTW, il y a beaucoup de citations dans Unicode, pas seulement celles mentionnées par vous et aussi si vous voulez faire la conversion de toute façon rappelez-vous que les conversions seront dépendantes de la locale.

Vérifier ICU - qui contient les routines de conversion Unicode les plus complètes.

0
répondu sorin 2011-05-28 19:03:54