将Unicodestring转换为转义的ASCIIstring

我怎样才能转换这个string:

This string contains the Unicode character Pi(π) 

转换成一个转义的ASCIIstring:

 This string contains the Unicode character Pi(\u03a0) 

反之亦然

在C#中可用的当前编码将π字符转换为“?”。 我需要保留这个angular色。

这个往返于\ xXXX格式。

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

输出:

这个函数包含一个unicode字符pi(π)

这个函数包含一个Unicode字符pi(\ u03a0)

这个函数包含一个unicode字符pi(π)

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

对于Unescape你可以简单地使用这个function:

 System.Text.RegularExpressions.Regex.Unescape(string) System.Uri.UnescapeDataString(string) 

我build议使用这种方法(使用UTF-8更好):

 UnescapeDataString(string) 

作为一个单行:

 var result = Regex.Replace(input, @"[^\x00-\x7F]", c => string.Format(@"\u{0:x4}", (int)c.Value[0])); 
 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(); } } 

所有非ASCII字符都被转换为Unicode代码点表示并附加到最​​终的string。

@Adam Sills的答案的一个小补丁,解决了类似于“c:\ u00ab \ otherdirectory \ ”和RegexOptions.Compiled这样的inputstring使得正则Regex编译快得多的情况下的FormatException

  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, @"\\"); } 

这是我目前的实现:

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

这通过了一个testing:

 public void TestBigUnicode() { var s = "\U00020000"; var encoded = s.EncodeNonAsciiCharacters(); var decoded = encoded.DecodeEncodedNonAsciiCharacters(); Assert.Equals(s, decoded); } 

与编码值: "\ud840\udc00"

这个实现使用了一个StringBuilderCache (参考源链接)

您需要在Encoding类中使用Convert()方法:

  • 创build一个表示ASCII编码的Encoding对象
  • 创build一个表示Unicode编码的Encoding对象
  • 使用源编码,目标编码和要编码的string调用Encoding.Convert()

这里有一个例子:

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

要存储实际的Unicode代码点,您必须首先将string的UTF-16代码单元解码为UTF-32代码单元(目前与Unicode代码点相同)。 为此,使用System.Text.Encoding.UTF32.GetBytes() ,然后根据需要将结果字节写入StringBuilder ,即

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