Как создать строку с суррогатной парой внутри нее?

Я видел этот пост в блоге Джона Скита, где он говорит о реверсировании строки. Я хотел попробовать пример, который он показал мне, но, похоже, это сработало... это заставляет меня думать, что я понятия не имею, как создать строку, содержащую суррогатную пару, которая фактически приведет к сбою разворота строки. Как на самом деле можно создать строку с суррогатной парой в ней, чтобы я мог сам увидеть неудачу?

2 ответов


термин "суррогатная пара" относится к средству кодирования символов Юникода с высокими кодовыми точками в UTF-16 схема кодирования (см. на этой странице для получения дополнительной информации);

на 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 затем проверьте строковые значения с помощью отладчика. Джон Скит чертовски прав... строки и даты кажутся легкими, но это абсолютно не так.


самый простой способ-это использовать \U######## здесь U - это капитал, а # обозначим ровно восемь шестнадцатеричных цифр. Если значение превышает 0000FFFF шестнадцатеричная, суррогатная пара будет необходима:

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

вы можете проверить myString.Length чтобы увидеть, что один символ Юникода занимает два .NET Char значения. Обратите внимание, что char тип имеет пару static методы, которые помогут вам определить, является ли char является частью суррогатной пары.

если вы используйте язык .NET, который не имеет чего-то вроде \U######## escape-последовательность, вы можете использовать метод ConvertFromUtf32, например:

string fourCircles = char.ConvertFromUtf32(0x1F01C);

дополнение: если исходный файл C# имеет кодировку, которая позволяет использовать все символы Юникода, такие как UTF-8, вы можете просто поместить charater непосредственно в файл (путем копирования-вставки). Например:

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

символ UTF-8 закодирован в исходном файле (в моем примере), но будет закодирован UTF-16 (суррогатные пары) когда приложение запускается и строка находится в памяти.

(не уверен, что программное обеспечение переполнения стека правильно обрабатывает мой символ маджонга. Попробуйте нажать " Изменить "на этот ответ и скопировать-вставить из текста там, если" смешного " символа здесь нет.)