Выдерживает сравнение два байта [] utf-8 закодировали, представляет то же в виде строки как сравнение двух строк unicode?

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

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

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

Действительно ли это верно?

9
задан Eloff 13 August 2010 в 16:44
поделиться

5 ответов

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

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

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

  • U+00e9 (LATIN SMALL LETTER E WITH ACUTE), или
  • U+0065 (LATIN SMALL LETTER E) с последующим U+0301 (COMBINING ACUTE ACCENT).

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

5
ответ дан 4 December 2019 в 10:30
поделиться

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

6
ответ дан 4 December 2019 в 10:30
поделиться

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

Например, À может быть записано как одна кодовая точка ( U + 00C0 ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА A С ТЯЖЕЛЫМ) или как две кодовые точки ( U + 0041 ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА A U + 0300 ОБЪЕДИНЕНИЕ МОЩНОГО АКЦЕНТА).

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

3
ответ дан 4 December 2019 в 10:30
поделиться

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

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

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

6
ответ дан 4 December 2019 в 10:30
поделиться

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

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

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

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

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

0
ответ дан 4 December 2019 в 10:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: