返回C#中的字符代码点

如何返回角色的Unicode代码点 ? 例如,如果输入为“A”,则输出应为“U + 0041”。 理想情况下,解决方案应该照顾代理对 。

代码点是指根据Unicode的实际代码点,它与代码单元不同(UTF8具有8位代码单元,UTF16具有16位代码单元,UTF32具有32位代码单元,在后一种情况下为值考虑到字节序后,等于代码点)。

很容易,因为C#中的字符实际上是UTF16代码点:

char x = 'A'; Console.WriteLine("U+{0:x4}", (int)x); 

为了解决这些注释,C#中的char是一个16位数字,并保存一个UTF16代码点。 位空间16以上的代码点不能用C#字符表示。 C#中的字符不是可变宽度。 然而, 字符串可以具有彼此跟随的2个字符,每个字符是代码单元,形成UTF16代码点。 如果您有一个字符串输入和16位空间之上的字符,您可以使用char.IsSurrogatePairChar.ConvertToUtf32 ,如另一个答案所示:

 string input = .... for(int i = 0 ; i < input.Length ; i += Char.IsSurrogatePair(input,i) ? 2 : 1) { int x = Char.ConvertToUtf32(input, i); Console.WriteLine("U+{0:X4}", x); } 

以下代码将string输入的代码点写入控制台:

 string input = "\uD834\uDD61"; for (var i = 0; i < input.Length; i += char.IsSurrogatePair(input, i) ? 2 : 1) { var codepoint = char.ConvertToUtf32(input, i); Console.WriteLine("U+{0:X4}", codepoint); } 

输出:

  U + 1D161 

由于.NET中的字符串是UTF-16编码的,因此构成字符串的char值需要首先转换为UTF-32。

实际上@Yogendra Singh的答案中有一些优点,目前唯一一个负面投票的人。 这项工作可以这样完成

  public static IEnumerable Utf8ToCodePoints(this string s) { var utf32Bytes = Encoding.UTF32.GetBytes(s); var bytesPerCharInUtf32 = 4; Debug.Assert(utf32bytes.Length % bytesPerCharInUtf32 == 0); for (int i = 0; i < utf32bytes.Length; i+= bytesPerCharInUtf32) { yield return BitConverter.ToInt32(utf32bytes, i); } } 

经过测试

  var surrogatePairInput = "abc💩"; Debug.Assert(surrogatePairInput.Length == 5); var pointsAsString = string.Join(";" , surrogatePairInput .Utf8ToCodePoints() .Select(p => $"U+{p:X4}")); Debug.Assert(pointsAsString == "U+0061;U+0062;U+0063;U+1F4A9"); 

示例是相关的,因为poo堆被表示为代理对。

C#无法在char存储unicode代码点,因为char只有2个字节,unicode代码点通常超过该长度。 解决方案是将代码点表示为字节序列(作为字节数组或“展平”为32位原语)或字符串。 接受的答案转换为UTF32,但这并不总是理想的。

这是我们用于将字符串拆分为其unicode代码点组件的代码,但保留了本机UTF-16编码。 结果是一个可枚举的,可用于在C#/ .NET中本地比较(子)字符串:

  public class InvalidEncodingException : System.Exception { } public static IEnumerable UnicodeCodepoints(this string s) { for (int i = 0; i < s.Length; ++i) { if (Char.IsSurrogate(s[i])) { if (s.Length < i + 2) { throw new InvalidEncodingException(); } yield return string.Format("{0}{1}", s[i], s[++i]); } else { yield return string.Format("{0}", s[i]); } } } } 
 public static string ToCodePointNotation(char c) { return "U+" + ((int)c).ToString("X4"); } Console.WriteLine(ToCodePointNotation('a')); //U+0061 

我在msdn论坛上找到了一个小方法。 希望这可以帮助。

  public int get_char_code(char character){ UTF32Encoding encoding = new UTF32Encoding(); byte[] bytes = encoding.GetBytes(character.ToString().ToCharArray()); return BitConverter.ToInt32(bytes, 0); }