Сравнивает ли два байта [] строк в кодировке utf-8 то же самое, что и сравнение двух строк в кодировке Юникод? - PullRequest
8 голосов
/ 13 августа 2010

Я нашел это в статье в википедии на utf-8:

Сортировка строк UTF-8 в виде массивов беззнаковых байтов даст те же результаты, что и сортировка их на основе кодовых точек Unicode.

Это заставило бы меня поверить, что для целей сравнения (сортировка, двоичный поиск и т. Д.), Что сравнение двух байтовых массивов (т.е. побайтовых байтов, подобных memcmp) строк в кодировке utf-8, даст те же результаты, что и сравнение фактические строки Unicode.

Это правда?

Ответы [ 5 ]

5 голосов
/ 13 августа 2010

Это то же самое, что и кодовая точка для сравнения кодовых точек, то есть та, которая не обращает внимания на свертывание, культурные упорядочения, композицию или что-либо, кроме значения Unicode.

Это довольно бесполезно, если рассматривать строки как текст, понятный человеку, но иногда вам просто нужно иметь возможность упорядочивать строки в порядке, поскольку некоторые алгоритмы (бинарный поиск, как вы говорите) нуждаютсяпоследовательное упорядочение, но детали этого непротиворечивого упорядочения не имеют существенного значения.

Важно отметить, что порядковое сравнение строк, предлагаемых .NET, работает на внутреннем UTF-16, который не поддерживает порядок кодов.Если мы сравним строку только с символом U + FF61 и строку только с символом U + 10002, тогда .NET сохранит последние в виде суррогатных пар 0xD800 и 0XDC02.

Следовательно:

string.CompareOrdinal("\U0000ff61", "\U00010002");

и

string.Compare("\U0000ff61", "\U00010002", StringComparison.Ordinal);

оба возвращают значения, большие нуля, даже несмотря на то, что первое меньше в значении кода, чем второе (я использовал форму \ U, а не форму \ uчтобы сделать это более понятным).

Если под "фактическими строками Unicode" вы подразумеваете строки .NET UTF-16, то ответ на ваш вопрос - нет, по причине, противоположной той, которая привела вас к размышлениюэто может сработать.

5 голосов
/ 13 августа 2010

Да, учитывая, что есть взаимно-однозначное отображение между байтами последовательностей в кодировке UTF-8 и кодовыми точками Unicode.

Однако есть способ сравнить строки Unicode, кроме просмотра необработанных кодовых точек,Если вы просто смотрите на кодовые точки - или байты UTF-8 - как числа, то вы упускаете логику сравнения для конкретной культуры.

Чтобы правильно выполнить сравнение и сортировку для конкретной культуры, в .NET вам следуетиспользуйте стандартные функции сравнения строк.

5 голосов
/ 13 августа 2010

Это зависит от того, что вы подразумеваете под «сравнением фактических строк Юникода».

Если вы просто собираетесь сравнивать кодовые точки (как 32-разрядные числа) вместо кодированных точек в кодировке UTF-8, тогда ответ - да: это даст те же результаты. Отображение из кодовых точек в байты в кодировке UTF-8 является взаимно-однозначным.

Если вы собираетесь сделать правильное сравнение строк в Юникоде, вместо байтового сравнения UTF-8, ответ - нет. В Юникоде могут быть разные способы представления одного и того же символа. Например, é может быть представлен (как минимум) двумя способами:

  • U+00e9 (LATIN SMALL LETTER E WITH ACUTE) или
  • U+0065 (LATIN SMALL LETTER E) и U+0301 (COMBINING ACUTE ACCENT).

Правильно написанная функция сравнения Unicode будет считать эти два идентичными.

3 голосов
/ 13 августа 2010

Нет, это не так.

Например, может быть записано как одна кодовая точка (U+00C0 LATIN CAPITAL LETTER A WITH GRAVE) или как две кодовые точки (U+0041 LATIN CAPITAL LETTER A U+0300 COMBINING GRAVE ACCENT).

Оба представления должны сравниваться одинаково, но будут иметь разные байтовые кодировки.

0 голосов
/ 13 августа 2010

Я нашел это в статье в википедии на utf-8:

Сортировка строк UTF-8 в виде массивов байтов без знака даст те же результаты, что и их сортировка на основе кода Unicodepoints.

Это заставило бы меня поверить в то, что для целей сравнения (сортировка, двоичный поиск и т. д.) сравниваются два байтовых массива (то есть побайтно, как memcmp) кодированных строк utf-8.даст те же результаты, что и сравнение фактических строк Юникода.

Все это зависит от того, что вы подразумеваете под «фактическими строками Юникода» и что вы подразумеваете под «сравнением».В .Net Framework строки представлены в формате UTF-16 Unicode.Простое двоичное сравнение между строками UTF-16 приведет к другому порядку сортировки, чем то же сравнение между строками UTF-8 и UTF-32 (версия кода, на которую есть ссылка в кавычке).

Но двоичное сравнениени одна из этих вещей не очень полезна.Вы должны использовать встроенные культурно-ориентированные сравнения.Это потому, что две строки, которые для всех намерений и целей одинаковы, могут быть построены из разных последовательностей кодовых точек.Встроенные сравнения учитывают эти вещи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...