如何创建一个带有代理对的字符串?

时间:2013-01-15 22:06:55

标签: c# string utf-16 utf-32 surrogate-pairs

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

2 个答案:

答案 0 :(得分:17)

最简单的方法是使用\U########U为大写,#正好表示八位十六进制数字。如果值超过0000FFFF十六进制,则需要代理对:

string myString = "In the game of mahjong \U0001F01C denotes the Four of circles";

您可以检查myString.Length以查看一个Unicode字符占用两个.NET Char值。请注意,char类型有两种static方法可帮助您确定char是否是代理项对的一部分。

如果使用的.NET语言不具有\U########转义序列,则可以使用方法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软件是否正确处理我的麻将字符。如果“滑稽”字符不在此处,请尝试点击“编辑”到这个答案并从那里复制粘贴文本。)

答案 1 :(得分:11)

术语“代理对”是指在UTF-16编码方案中使用高代码点编码Unicode字符的方法(有关详细信息,请参阅this page);

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

这是使用称为代理项的成对代码点完成的。代理字符分为两个不同的范围,称为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);

然后用调试器检查字符串值。 Jon Skeet是对的......字符串和日期似乎很容易,但绝对不是。