c# - convertir - Convierta una cadena Unicode en una cadena ASCII escapada
encoding utf 8 acentos c# (9)
Aquí está mi implementación actual:
public static class UnicodeStringExtensions
{
public static string EncodeNonAsciiCharacters(this string value) {
var bytes = Encoding.Unicode.GetBytes(value);
var sb = StringBuilderCache.Acquire(value.Length);
bool encodedsomething = false;
for (int i = 0; i < bytes.Length; i += 2) {
var c = BitConverter.ToUInt16(bytes, i);
if ((c >= 0x20 && c <= 0x7f) || c == 0x0A || c == 0x0D) {
sb.Append((char) c);
} else {
sb.Append($"//u{c:x4}");
encodedsomething = true;
}
}
if (!encodedsomething) {
StringBuilderCache.Release(sb);
return value;
}
return StringBuilderCache.GetStringAndRelease(sb);
}
public static string DecodeEncodedNonAsciiCharacters(this string value)
=> Regex.Replace(value,/*language=regexp*/@"(?://u[a-fA-F0-9]{4})+", Decode);
static readonly string[] Splitsequence = new [] { "//u" };
private static string Decode(Match m) {
var bytes = m.Value.Split(Splitsequence, StringSplitOptions.RemoveEmptyEntries)
.Select(s => ushort.Parse(s, NumberStyles.HexNumber)).SelectMany(BitConverter.GetBytes).ToArray();
return Encoding.Unicode.GetString(bytes);
}
}
Esto pasa una prueba:
public void TestBigUnicode() {
var s = "/U00020000";
var encoded = s.EncodeNonAsciiCharacters();
var decoded = encoded.DecodeEncodedNonAsciiCharacters();
Assert.Equals(s, decoded);
}
con el valor codificado: "/ud840/udc00"
Esta implementación hace uso de StringBuilderCache (enlace fuente de referencia)
¿Cómo puedo convertir esta cadena?
This string contains the Unicode character Pi(π)
en una cadena ASCII escapada:
This string contains the Unicode character Pi(/u03a0)
y viceversa ?
La codificación actual disponible en C # convierte el carácter π a "?". Necesito preservar ese personaje.
Como un trazador de líneas:
var result = Regex.Replace(input, @"[^/x00-/x7F]", c =>
string.Format(@"/u{0:x4}", (int)c.Value[0]));
Esto va y viene desde y hacia el formato / uXXXX.
class Program {
static void Main( string[] args ) {
string unicodeString = "This function contains a unicode character pi (/u03a0)";
Console.WriteLine( unicodeString );
string encoded = EncodeNonAsciiCharacters(unicodeString);
Console.WriteLine( encoded );
string decoded = DecodeEncodedNonAsciiCharacters( encoded );
Console.WriteLine( decoded );
}
static string EncodeNonAsciiCharacters( string value ) {
StringBuilder sb = new StringBuilder();
foreach( char c in value ) {
if( c > 127 ) {
// This character is too big for ASCII
string encodedValue = "//u" + ((int) c).ToString( "x4" );
sb.Append( encodedValue );
}
else {
sb.Append( c );
}
}
return sb.ToString();
}
static string DecodeEncodedNonAsciiCharacters( string value ) {
return Regex.Replace(
value,
@"//u(?<Value>[a-zA-Z0-9]{4})",
m => {
return ((char) int.Parse( m.Groups["Value"].Value, NumberStyles.HexNumber )).ToString();
} );
}
}
Productos:
Esta función contiene un carácter unicode pi (π)
Esta función contiene un carácter unicode pi (/ u03a0)
Esta función contiene un carácter unicode pi (π)
Necesita usar el método Convert()
en la clase de Encoding
:
- Crear un objeto de
Encoding
que represente la codificación ASCII - Crear un objeto de
Encoding
que represente la codificación Unicode - Llamar a
Encoding.Convert()
con la codificación de origen, la codificación de destino y la cadena a codificar
Hay un ejemplo here :
using System;
using System.Text;
namespace ConvertExample
{
class ConvertExampleClass
{
static void Main()
{
string unicodeString = "This string contains the unicode character Pi(/u03a0)";
// Create two different encodings.
Encoding ascii = Encoding.ASCII;
Encoding unicode = Encoding.Unicode;
// Convert the string into a byte[].
byte[] unicodeBytes = unicode.GetBytes(unicodeString);
// Perform the conversion from one encoding to the other.
byte[] asciiBytes = Encoding.Convert(unicode, ascii, unicodeBytes);
// Convert the new byte[] into a char[] and then into a string.
// This is a slightly different approach to converting to illustrate
// the use of GetCharCount/GetChars.
char[] asciiChars = new char[ascii.GetCharCount(asciiBytes, 0, asciiBytes.Length)];
ascii.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0);
string asciiString = new string(asciiChars);
// Display the strings created before and after the conversion.
Console.WriteLine("Original string: {0}", unicodeString);
Console.WriteLine("Ascii converted string: {0}", asciiString);
}
}
}
Para Unescape , simplemente puede usar estas funciones:
System.Text.RegularExpressions.Regex.Unescape(string)
System.Uri.UnescapeDataString(string)
Sugiero usar este método (funciona mejor con UTF-8):
UnescapeDataString(string)
Para almacenar los puntos de código Unicode reales, primero debe decodificar las unidades de códigos UTF-16 de String a las unidades de códigos UTF-32 (que actualmente son las mismas que los puntos de código Unicode). Use System.Text.Encoding.UTF32.GetBytes()
para eso y luego escriba los bytes resultantes en StringBuilder
según sea necesario, es decir,
static void Main(string[] args)
{
String originalString = "This string contains the unicode character Pi(π)";
Byte[] bytes = Encoding.UTF32.GetBytes(originalString);
StringBuilder asAscii = new StringBuilder();
for (int idx = 0; idx < bytes.Length; idx += 4)
{
uint codepoint = BitConverter.ToUInt32(bytes, idx);
if (codepoint <= 127)
asAscii.Append(Convert.ToChar(codepoint));
else
asAscii.AppendFormat("//u{0:x4}", codepoint);
}
Console.WriteLine("Final string: {0}", asAscii);
Console.ReadKey();
}
Un pequeño parche para la respuesta de @Adam Sills que resuelve FormatException
en casos donde la cadena de entrada como "c: / u00ab / otherdirectory / " más RegexOptions.Compiled
hace que la compilación Regex
mucho más rápida:
private static Regex DECODING_REGEX = new Regex(@"//u(?<Value>[a-fA-F0-9]{4})", RegexOptions.Compiled);
private const string PLACEHOLDER = @"#!#";
public static string DecodeEncodedNonAsciiCharacters(this string value)
{
return DECODING_REGEX.Replace(
value.Replace(@"//", PLACEHOLDER),
m => {
return ((char)int.Parse(m.Groups["Value"].Value, NumberStyles.HexNumber)).ToString(); })
.Replace(PLACEHOLDER, @"//");
}
class Program
{
static void Main(string[] args)
{
char[] originalString = "This string contains the unicode character Pi(π)".ToCharArray();
StringBuilder asAscii = new StringBuilder(); // store final ascii string and Unicode points
foreach (char c in originalString)
{
// test if char is ascii, otherwise convert to Unicode Code Point
int cint = Convert.ToInt32(c);
if (cint <= 127 && cint >= 0)
asAscii.Append(c);
else
asAscii.Append(String.Format("//u{0:x4} ", cint).Trim());
}
Console.WriteLine("Final string: {0}", asAscii);
Console.ReadKey();
}
}
Todos los caracteres no ASCII se convierten a su representación de punto de código Unicode y se anexan a la cadena final.
string StringFold(string input, Func<char, string> proc)
{
return string.Concat(input.Select(proc).ToArray());
}
string FoldProc(char input)
{
if (input >= 128)
{
return string.Format(@"/u{0:x4}", (int)input);
}
return input.ToString();
}
string EscapeToAscii(string input)
{
return StringFold(input, FoldProc);
}