web-dev-qa-db-fra.com

Comment convertir (translittérate) une chaîne de UTF8 à ASCII (octet unique) en C #?

J'ai un objet de chaîne

"Avec plusieurs personnages et même des caractères spéciaux"

J'essaie d'utiliser

UTF8Encoding utf8 = new UTF8Encoding();
ASCIIEncoding ascii = new ASCIIEncoding();

objets afin de convertir cette chaîne en ASCII. Puis-je demander à quelqu'un d'apporter une lumière à cette tâche simple, qui chasse mon après-midi.

Modifier 1: Ce que nous essayons d'accomplir me débarrasse de caractères spéciaux comme certaines des apostrophes Windows spéciaux. Le code que j'ai posté ci-dessous comme réponse ne s'en occupera pas de cela. Essentiellement

O'Brian deviendra O? Brian. où 'est l'une des apostrophes spéciales

11
Geo

C'était en réponse à votre autre question qui semble être supprimée ... Le point est toujours debout.

Ressemble à un classique Unicode to ASCII LIVE . L'astuce serait de trouver ça se passe.

.NET fonctionne bien avec Unicode, en supposant on dit que c'est Unicode de commencer (ou à gauche à la valeur par défaut).

Mon suppose est que votre application de réception ne peut pas le gérer. Donc, j'utiliserais probablement le asciiencoderavec AN ENCODERREPLEMENTCYFULBACKBACK avec string.empty:

using System.Text;

string inputString = GetInput();
var encoder = ASCIIEncoding.GetEncoder();
encoder.Fallback = new EncoderReplacementFallback(string.Empty);

byte[] bAsciiString = encoder.GetBytes(inputString);

// Do something with bytes...
// can write to a file as is
File.WriteAllBytes(FILE_NAME, bAsciiString);
// or turn back into a "clean" string
string cleanString = ASCIIEncoding.GetString(bAsciiString); 
// since the offending bytes have been removed, can use default encoding as well
Assert.AreEqual(cleanString, Default.GetString(bAsciiString));

Bien sûr, dans les vieux jours, nous venons de boucler et de supprimer tous les caractères plus de 127 ... Eh bien, ceux d'entre nous aux États-Unis au moins. ;)

20
Mark Brackett

J'ai pu comprendre. Au cas où quelqu'un veut savoir sous le code qui a fonctionné pour moi:

ASCIIEncoding ascii = new ASCIIEncoding();
byte[] byteArray = Encoding.UTF8.GetBytes(sOriginal);
byte[] asciiArray = Encoding.Convert(Encoding.UTF8, Encoding.ASCII, byteArray);
string finalString = ascii.GetString(asciiArray);

Faites-moi savoir s'il y a une façon plus simple de le faire.

12
Geo

Pour quiconque aime les méthodes de vulgarisation, celle-ci fait le tour pour nous.

using System.Text;

namespace System
{
    public static class StringExtension
    {
        private static readonly ASCIIEncoding asciiEncoding = new ASCIIEncoding();

        public static string ToAscii(this string dirty)
        {
            byte[] bytes = asciiEncoding.GetBytes(dirty);
            string clean = asciiEncoding.GetString(bytes);
            return clean;
        }
    }
}

(Espace de noms système afin qu'il soit disponible à peu près automatiquement pour toutes nos chaînes.)

7
Peter Drier

Basé sur la réponse de Mark ci-dessus (et le commentaire de Geo), j'ai créé une version de deux lignes pour supprimer tout ASCII Cas d'exception d'une chaîne. Fourni pour les personnes à la recherche de cette réponse (comme je l'ai fait).

using System.Text;

// Create encoder with a replacing encoder fallback
var encoder = ASCIIEncoding.GetEncoding("us-ascii", 
    new EncoderReplacementFallback(string.Empty), 
    new DecoderExceptionFallback());

string cleanString = encoder.GetString(encoder.GetBytes(dirtyString)); 
5
tonycoupland

Si vous souhaitez une représentation de 8 bits de caractères utilisés dans de nombreux codages, cela peut vous aider.

Vous devez changer de variable télécommandation à tout encodage que vous voulez.

Encoding targetEncoding = Encoding.GetEncoding(874); // Your target encoding
Encoding utf8 = Encoding.UTF8;

var stringBytes = utf8.GetBytes(Name);
var stringTargetBytes = Encoding.Convert(utf8, targetEncoding, stringBytes);
var ascii8BitRepresentAsCsString = Encoding.GetEncoding("Latin1").GetString(stringTargetBytes);
1
Rapeapach Suwasri