返回C#中的字符代码点

FSm*_*FSm 17 c# unicode unicode-string

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

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

dtb*_*dtb 13

以下代码将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);
}
Run Code Online (Sandbox Code Playgroud)

输出:

U+1D161

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

  • @Esailija:我不确定什么更令人困惑:使用名为`ConvertToUtf32`的方法转换为Unicode代码点,或转换为UTF-32并将结果视为Unicode代码点.最后,这可能是分裂的头发. (2认同)

Dig*_*Dan 12

在.NET Core 3.0或更高版本中,您可以使用Rune Struct

\n
// Note that  and  are encoded using surrogate pairs\n// but A, B, C and \xe2\x9c\x8b are not\nvar runes = "ABC\xe2\x9c\x8b".EnumerateRunes();\n\nforeach (var r in runes)\n    Console.Write($"U+{r.Value:X4} ");\n        \n// Writes: U+0041 U+0042 U+0043 U+270B U+1F609 U+1F44D\n
Run Code Online (Sandbox Code Playgroud)\n


dri*_*iis 10

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

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

为了解决这些注释,charC#中的A 是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);
}
Run Code Online (Sandbox Code Playgroud)

  • 它们是unicode代码单元,而不是代码点.那些需要多个代码单元的字符呢? (5认同)
  • @driis:我没有向你投票,我只是提出一个澄清点. (2认同)
  • @Qaesar小写a(''a'`)是'U + 0061`,大写a(''A'`)是'U + 0041` (2认同)
  • 对不起,如果我们让你感到困惑.问题是Unicode编码实际上有点复杂,即使它们乍一看似乎也不是这样.这个答案中的代码,或者@dtb发布的代码,对你来说都很好.如果你想要更多背景,我可以推荐http://www.joelonsoftware.com/articles/Unicode.html. (2认同)