如何归还角色的Unicode Code Point?例如,如果输入为“A”,则输出应为“U + 0041”。理想情况下,解决方案应该处理surrogate pairs。
使用代码点我指的是实际代码点according to Unicode,它与 code unit 不同(UTF8具有8位代码单元, UTF16具有16位代码单元,UTF32具有32位代码单元,在后一种情况下,该值等于代码点,在考虑到字节序后)。
答案 0 :(得分: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);
}
输出:
U+1D161
由于.NET中的字符串是UTF-16编码的,因此构成字符串的char
值需要先转换为UTF-32。
答案 1 :(得分:8)
很简单,因为C#中的字符实际上是UTF16代码点:
char x = 'A';
Console.WriteLine("U+{0:x4}", (int)x);
为了解决这些注释,C#中的char
是一个16位数字,并保存一个UTF16代码点。位空间16以上的代码点不能用C#字符表示。 C#中的字符不是可变宽度。然而,字符串可以具有彼此跟随的2个字符,每个字符是代码单元,形成UTF16代码点。如果你有一个字符串输入和16位空格之上的字符,你可以使用char.IsSurrogatePair
和Char.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);
}
答案 2 :(得分:2)
实际上@Yogendra Singh的答案有一些优点,目前唯一一个负面投票的人。 这项工作可以像这样完成
public static IEnumerable<int> 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堆被表示为代理对。
答案 3 :(得分:1)
C#无法在char
中存储unicode代码点,因为char
只有2个字节,而unicode代码点通常超过该长度。解决方案是将代码点表示为字节序列(作为字节数组或“展平”为32位原语)或字符串。接受的答案转换为UTF32,但这并不总是理想的。
这是我们用于将字符串拆分为其unicode代码点组件的代码,但保留了本机UTF-16编码。结果是一个可枚举的,可用于在C#/ .NET中本地比较(子)字符串:
public class InvalidEncodingException : System.Exception
{ }
public static IEnumerable<string> 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]);
}
}
}
}
答案 4 :(得分:1)
在 .NET Core 3.0 或更高版本中,您可以使用 Rune Struct:
// Note that ? and ? are encoded using surrogate pairs
// but A, B, C and ✋ are not
var runes = "ABC✋??".EnumerateRunes();
foreach (var r in runes)
Console.Write($"U+{r.Value:X4} ");
// Writes: U+0041 U+0042 U+0043 U+270B U+1F609 U+1F44D
答案 5 :(得分:-1)
public static string ToCodePointNotation(char c)
{
return "U+" + ((int)c).ToString("X4");
}
Console.WriteLine(ToCodePointNotation('a')); //U+0061
答案 6 :(得分:-2)
我在msdn forum找到了一个小方法。希望这会有所帮助。
public int get_char_code(char character){
UTF32Encoding encoding = new UTF32Encoding();
byte[] bytes = encoding.GetBytes(character.ToString().ToCharArray());
return BitConverter.ToInt32(bytes, 0);
}