如何创建一个带有代理对的字符串?
我在Jon Skeet的博客上看到这篇文章 ,他谈到了字符串翻转。 我想尝试他自己展示的例子,但它似乎有效……这让我相信我不知道如何创建一个包含代理对的字符串,这实际上会导致字符串反转失败。 如何实际创建一个带有代理对的字符串,以便我自己可以看到失败?
术语“代理对”是指在UTF-16
编码方案中使用高代码点编码Unicode字符的方法(有关更多信息,请参阅此页 );
在Unicode
字符编码中,字符映射到0x000000
和0x10FFFF
之间的值。 在内部, UTF-16
编码方案用于存储Unicode
文本的字符串,其中考虑了双字节( 16-bit
)代码序列。 由于两个字节只能包含从0x0000
到0xFFFF
的字符范围,因此使用一些额外的复杂度来存储高于此范围的值( 0x010000
到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);
然后用调试器检查字符串值。 Jon Skeet是对的……字符串和日期似乎很容易,但绝对不是。
最简单的方法是使用\U########
,其中U
是大写, #
表示正好八个hex数字。 如果该值超过0000FFFF
hex,则需要一个代理对:
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软件是否正确处理我的麻将字符。如果“搞笑”字符不在此处,请尝试单击“编辑”到此答案并从那里复制粘贴文本。)