我在 Jon Skeet 的博客上看到了这篇文章,他谈到了字符串反转。我想尝试他向自己展示的示例,但它似乎有效......这让我相信我不知道如何创建一个包含代理对的字符串,这实际上会导致字符串反转失败。实际上如何创建一个带有代理对的字符串,以便我自己可以看到失败?
2 回答
最简单的方法是使用\U########
whereU
是大写字母,而 the#
正好表示八个十六进制数字。如果值超过0000FFFF
十六进制,则需要一个代理对:
string myString = "In the game of mahjong \U0001F01C denotes the Four of circles";
您可以检查myString.Length
一个 Unicode 字符是否占用两个 .NETChar
值。请注意,该char
类型有几个static
方法可以帮助您确定 achar
是否是代理对的一部分。
如果您使用没有\U########
转义序列之类的 .NET 语言,则可以使用 method ConvertFromUtf32
,例如:
string fourCircles = char.ConvertFromUtf32(0x1F01C);
另外:如果您的 C# 源文件具有允许所有 Unicode 字符的编码,例如 UTF-8,您可以直接将字符放入文件中(通过复制粘贴)。例如:
string myString = "In the game of mahjong denotes the Four of circles";
该字符在源文件(在我的示例中)中是 UTF-8 编码的,但是当应用程序运行并且字符串在内存中时,它将是 UTF-16 编码(代理对)。
(不确定 Stack Overflow 软件是否正确处理了我的麻将字符。如果“有趣”字符不在这里,请尝试单击此答案的“编辑”并从那里的文本中复制粘贴。)
术语“代理对”是指在UTF-16
编码方案中使用高代码点对 Unicode 字符进行编码的一种方式(有关更多信息,请参见此页面);
在Unicode
字符编码中,字符映射到 和 之间的0x000000
值0x10FFFF
。在内部,UTF-16
编码方案用于存储考虑Unicode
到两字节 ( 16-bit
) 代码序列的文本字符串。由于两个字节只能包含从0x0000
to的字符范围0xFFFF
,因此使用一些额外的复杂性来存储超出此范围 ( 0x010000
to 0x10FFFF
) 的值。
这是使用称为代理的代码点对完成的。代理字符分为两个不同的范围,称为low surrogates
和high surrogates
,这取决于它们是否被允许在两个代码序列的开头或结尾。
自己试试这个:
String surrogate = "abc" + Char.ConvertFromUtf32(Int32.Parse("2A601", NumberStyles.HexNumber)) + "def";
Char[] surrogateArray = surrogate.ToCharArray();
Array.Reverse(surrogateArray);
String surrogateReversed = new String(surrogateArray);
或者这个,如果你想坚持博客示例:
String surrogate = "Les Mise" + Char.ConvertFromUtf32(Int32.Parse("0301", NumberStyles.HexNumber)) + "rables";
Char[] surrogateArray = surrogate.ToCharArray();
Array.Reverse(surrogateArray);
String surrogateReversed = new String(surrogateArray);
nnd 然后使用调试器检查字符串值。Jon Skeet 说得对……字符串和日期看起来很简单,但绝对不是。