例如,我有这个 Unicode 字符串,它由 Cyclone 组成和 Japanese Castle在 C# 和 .NET 中定义,它使用 UTF-16 作为其 CLR 字符串编码:
var value = "🌀🏯";
如果你检查这个,你会很快发现 value.Length = 4
因为 C# 使用 UTF-16 编码的字符串,所以出于这些原因我不能只循环每个字符并得到它UTF-32 十进制值:foreach (var character in value) result = (ulong)character;
。这就引出了一个问题,我怎样才能得到任何字符串中每个字符的 UTF-32 十进制值?
Cyclone 应为 127744
,Japanese CaSTLe 应为 127983
,但我正在寻找一个通用答案,它可以采用任何 C# 字符串并始终生成 UTF-32 十进制其中每个字符的值。
我什至试过看一下 Char.ConvertToUtf32 ,但这似乎是有问题的,例如:
var value = "a🌀c🏯";
长度为 6。那么,我如何知道新字符何时开始?例如:
Char.ConvertToUtf32(value, 0) 97 int
Char.ConvertToUtf32(value, 1) 127744 int
Char.ConvertToUtf32(value, 2) 'Char.ConvertToUtf32(value, 2)' threw an exception of type 'System.ArgumentException' int {System.ArgumentException}
Char.ConvertToUtf32(value, 3) 99 int
Char.ConvertToUtf32(value, 4) 127983 int
Char.ConvertToUtf32(value, 5) 'Char.ConvertToUtf32(value, 5)' threw an exception of type 'System.ArgumentException' int {System.ArgumentException}
还有:
public static int ConvertToUtf32(
char highSurrogate,
char lowSurrogate
)
但如果我也想使用它,我需要弄清楚什么时候我有代理对。你怎么做到的?
最佳答案
解决方案一
string value = "🌀🏯";
byte[] rawUtf32AsBytes = Encoding.UTF32.GetBytes(value);
int[] rawUtf32 = new int[rawUtf32AsBytes.Length / 4];
Buffer.BlockCopy(rawUtf32AsBytes, 0, rawUtf32, 0, rawUtf32AsBytes.Length);
方案二
string value = "🌀🏯";
List<int> rawUtf32list = new List<int>();
for (int i = 0; i < value.Length; i++)
{
if (Char.IsHighSurrogate(value[i]))
{
rawUtf32list.Add(Char.ConvertToUtf32(value[i], value[i + 1]));
i++;
}
else
rawUtf32list.Add((int)value[i]);
}
更新:
从 .NET Core 3.0 开始,我们有了代表 UTF32 字符的 Rune
结构:
string value = "a🌀c🏯";
var runes = value.EnumerateRunes();
// writes a:97, 🌀:127744, c:99, 🏯:127983
Console.WriteLine(String.Join(", ", runes.Select(r => $"{r}:{r.Value}")));
关于c# - 如何读取字符串中的字符作为它们的 UTF-32 十进制值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32141569/