14

我在 Jon Skeet 的博客上看到了这篇文章,他谈到了字符串反转。我想尝试他向自己展示的示例,但它似乎有效......这让我相信我不知道如何创建一个包含代理对的字符串,这实际上会导致字符串反转失败。实际上如何创建一个带有代理对的字符串,以便我自己可以看到失败?

4

2 回答 2

18

最简单的方法是使用\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 软件是否正确处理了我的麻将字符。如果“有趣”字符不在这里,请尝试单击此答案的“编辑”并从那里的文本中复制粘贴。)

于 2013-01-15T22:43:38.913 回答
14

术语“代理对”是指在UTF-16编码方案中使用高代码点对 Unicode 字符进行编码的一种方式(有关更多信息,请参见此页面);

Unicode字符编码中,字符映射到 和 之间的0x0000000x10FFFF。在内部,UTF-16编码方案用于存储考虑Unicode到两字节 ( 16-bit) 代码序列的文本字符串。由于两个字节只能包含从0x0000to的字符范围0xFFFF,因此使用一些额外的复杂性来存储超出此范围 ( 0x010000to 0x10FFFF) 的值。

这是使用称为代理的代码点对完成的。代理字符分为两个不同的范围,称为low surrogateshigh 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 说得对……字符串和日期看起来很简单,但绝对不是。

于 2013-01-15T22:23:15.303 回答