C# C中字符的返回码点#
如何返回角色的名称?例如,如果输入为“A”,则输出应为“U+0041”。理想情况下,解决方案应该考虑到这一点 对于代码点,我指的是实际的代码点,它不同于(UTF8有8位代码单元,UTF16有16位代码单元,UTF32有32位代码单元,在后一种情况下,在考虑到endianness后,值等于代码点)。简单,因为C#中的字符实际上是UTF16代码点:C# C中字符的返回码点#,c#,unicode,unicode-string,C#,Unicode,Unicode String,如何返回角色的名称?例如,如果输入为“A”,则输出应为“U+0041”。理想情况下,解决方案应该考虑到这一点 对于代码点,我指的是实际的代码点,它不同于(UTF8有8位代码单元,UTF16有16位代码单元,UTF32有32位代码单元,在后一种情况下,在考虑到endianness后,值等于代码点)。简单,因为C#中的字符实际上是UTF16代码点: char x = 'A'; Console.WriteLine("U+{0:x4}", (int)x); 为了处理注释,C#中的char是一个16位的
char x = 'A';
Console.WriteLine("U+{0:x4}", (int)x);
为了处理注释,C#中的char
是一个16位的数字,它包含一个UTF16代码点。位空间大于16的代码点不能用C#字符表示。C#中的字符宽度不可变。但是,一个字符串可以有两个字符相互跟随,每个字符都是一个代码单元,形成一个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);
}
字符串输入=。。。。
对于(int i=0;i
我在上找到了一个小方法。希望这有帮助
public int get_char_code(char character){
UTF32Encoding encoding = new UTF32Encoding();
byte[] bytes = encoding.GetBytes(character.ToString().ToCharArray());
return BitConverter.ToInt32(bytes, 0);
}
以下代码将
字符串
输入的代码点写入控制台:
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);
}
string input=“\uD834\uDD61”;
对于(变量i=0;i
输出:
U+1D161
由于.NET中的字符串是UTF-16编码的,因此需要首先将构成字符串的char
值转换为UTF-32。C#无法在char
中存储unicode码点,因为char
只有2个字节,unicode码点通常超过该长度。解决方案是将代码点表示为字节序列(字节数组或“展平”为32位原语)或字符串。公认的答案转换为UTF32,但这并不总是理想的
这是我们用来将字符串拆分为unicode代码点组件的代码,但保留了本机UTF-16编码。结果是可枚举的,可用于在C#/.NET中本机比较(子)字符串:
public类InvalidEncodingException:System.Exception
{ }
公共静态IEnumerable点(此字符串为s)
{
对于(int i=0;i
事实上@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);
}
}
公共静态IEnumerable Utf8ToCodePoints(此字符串为s)
{
var utf32Bytes=Encoding.UTF32.GetBytes;
var bytesPerCharInUtf32=4;
Assert(utf32bytes.Length%bytesPerCharInUtf32==0);
for(int i=0;i
测试
在.NET Core 3.0或更高版本中,您可以使用:
//请注意,它们是unicode代码单位,而不是代码点。那么需要多个代码单位的字符呢?@driis…与GregS相同comment@driis:我没有否决你的意见,我只是想说明一点。@Qaesar小写字母a('a'
)是U+0061
,大写字母a('a'
)是U+0041
如果我们让您感到困惑,很抱歉。问题是Unicode编码实际上有点复杂,尽管乍一看可能不是这样。这个答案中的代码,或者@dtb发布的代码,对您来说很好。如果您需要更多背景,我可以推荐。这是否会返回与(int)不同的内容字符
?如果字符
是代理项对的一半,会发生什么?@dtb(我知道答案很晚)。这段代码的有趣之处在于它显示了使用utf32编码
,但由于该方法只使用字符
,因此它没有效果,并且与(int)相同character
,虽然比cast慢得多。事实上,character.ToString().toCharray()
将始终返回一个项目数组(大小为2字节),而位转换器
将永远不会返回值>65535。原则上这是一个好主意,但它的呈现方式毫无用处。它不会转换为UTF-32,而是将代码点返回为整数,UTF-32是一种编码,而不是整数。这种命名方法传播了与microsoft将UTF-16LE编码标记为“unicode”一样的混乱“@Esailija:我不确定还有什么更令人困惑:使用名为ConvertToUtf32
的方法转换为Unicode代码点,或者转换为UTF-32并将结果视为Unicode代码点。你不能把转换成实际UTF-32的结果当作代码点,你需要从编码中解码代码点,就像从UTF-16或UTF-8中解码一样,只是更简单。但我明白为什么这会被视为吹毛求疵:p这个问题措辞严重错误。“返回字符的‘Unicode’”毫无意义,坦率地说,这是胡说八道。你的例子清楚地说明了你真正想要什么,但是标题需要修改。请这样做。@tchrist,谢谢你。。我更新了我的问题谢谢。我对你表示感谢。@Qaesar小写字母a('a'
)是U+0061
,大写字母a('a'
)是U
U+1D161
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]);
}
}
}
}
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);
}
}