Comment convertir (translittérer) une chaîne de utf8 en ASCII (octet unique) en c #?
-
20-08-2019 - |
Question
j'ai un objet chaîne
& "; avec plusieurs caractères 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 un peu de lumière à cette tâche simple, qui est la chasse de mon après-midi.
EDIT 1: Ce que nous essayons d'accomplir, c'est d'éliminer les caractères spéciaux, tels que certaines des apostrophes spéciales de Windows. Le code que j'ai posté ci-dessous comme réponse ne s'en occupera pas. Fondamentalement
O'Brian deviendra O? Brian. où est l'une des apostrophes spéciales
La solution
C’était en réponse à votre autre question, qui semble avoir été supprimée ... le point est toujours valable.
Ressemble à un problème classique entre Unicode et ASCII . Le truc serait de trouver où cela se produit.
.NET fonctionne bien avec Unicode, en supposant que soit dit que c'est Unicode pour commencer (ou à gauche par défaut).
Mon suppose que est que votre application de réception ne peut pas le gérer. Donc, j'utiliserais probablement le ASCIIEncoder avec un EncoderReplacementFallback 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, à l’époque, nous nous contentions de boucler et de supprimer tous les caractères supérieurs à 127 . . bien, ceux d’entre nous aux États-Unis au moins. ;)
Autres conseils
J'ai été capable de comprendre. Si quelqu'un veut savoir ci-dessous 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 existe un moyen plus simple de le faire.
Pour ceux qui aiment les méthodes d'extension, celle-ci fait l'affaire 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;
}
}
}
(L'espace de noms système est donc disponible presque automatiquement pour toutes nos chaînes.)
Sur la base de la réponse de Mark ci-dessus (et du commentaire de Geo), j'ai créé une version à deux lignes pour supprimer tous les cas d'exception ASCII d'une chaîne. Fourni aux personnes recherchant 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));
Si vous souhaitez une représentation sur 8 bits des caractères utilisés dans de nombreux codages, cela peut vous aider.
Vous devez remplacer la variable targetEncoding par le codage souhaité.
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);