2016-03-29 2 views
0

У меня есть требование, в котором мой код на C++ должен делать нечувствительное к регистру сравнение, не беспокоясь о том, закодирована ли строка или нет, или тип кодирования. Строка может быть ASCII или не-ASCII, мне просто нужно сохранить ее как есть и сравнить ее со второй строкой, не касаясь правильного языкового стандарта и т. Д.Как добиться unicode-agnostic нечувствительности к регистру в C++

Use case: Предположим, что мое приложение получает строку (предположим, что это имя файла) сначала как «Zoë Saldaña.txt», и сохраняет ее как есть. Впоследствии он получает еще одну строку «zoë saLdañA.txt», а сравнение между этой и первой строкой должно приводить к совпадению с использованием нескольких API. То же самое с именем файла «abc.txt» и «AbC.txt».

Я прочитал о ICU IBM и как он использует кодировку UTF-16 по умолчанию. Мне интересно знать:

  1. Если СИС предоставляет средства решений моих требований по бесшовно обработкам строк, независимо от их типа кодирования?

  2. Если ответ на вопрос 1. нет, то с использованием API-интерфейсов ICU безопасно нормализовать все строки (как ASCII, так и не ASCII) до UTF-16, а затем провести сравнение без учета регистра и другие операции ?

  3. Есть ли альтернативы, которые облегчают это?

Я прочитал это post, но это не совсем соответствует моим требованиям.

Спасибо!

+3

Вы не можете сделать без учета регистра сравнения, не зная локаль. В Турции «ФАЙЛ» должен * не * соответствовать «файлу». («FİLE» должен соответствовать «файлу», а «ФАЙЛ» должен соответствовать «fıle»). В случае, если это не очевидно, у турецкого есть пунктир-i, (i и İ) и бесцеремонный-i (ı и я). –

+0

Как закодированы ваши строки? Вы не можете сделать ничего полезного, если вы хотя бы не знаете, что такое кодировка источника. –

+1

Практический пример действительно немного глупо. Для имен файлов вы не можете произвольно решить, что они нечувствительны к регистру. Файлы в большинстве файловых систем, подобных Unix, зависят от вашего регистратора, независимо от того, нравится вам это или нет. Для Windows/NTFS они не чувствительны к регистру, используя таблицу case, хранящуюся на этом диске_! – MSalters

ответ

4

Требование невозможно. Компьютеры не работают с символами, они работают с числами. Но «нечувствительные к регистру» сравнения - это операции, которые работают над персонажами. Локали определяют, какие числа соответствуют тем символам, и поэтому они незаменимы.

Вышеприведенное относится не только ко всем прогаммирующим связям, это даже верно для сравнения с регистром. Отображение от символа к числу не всегда уникально. Это означает, что сравнение двух чисел не работает. Там может быть локаль, где символ 42 эквивалентен знаку 43. В Юникоде это еще хуже. Есть число последовательностей, которые имеют разную длину и по-прежнему эквивалентны. (предварительно скомпонованные и разложенные символы, в частности)

+2

Юникод ужасен, полный и полный кошмар. Самое страшное, насколько это лучше, чем все, что было раньше. –

+1

@MartinBonner: Ну, с около 6000 языков (без учета диалектов), имеющих одну кодировку, это вызов. Тем не менее, вы могли бы теоретически ввести «Unicode Light» без абсолютно глупых вещей, таких как эмои, но по какой цене? – MSalters

+0

Emoji - это не проблема (они просто «персонажи»). Это нечто вроде «ЛАТИНСКОГО КАПИТАЛА ПИСЬМА С КОЛЬЦОМ ВЫШЕ» и «ЛАТИНСКОЕ КАПИТАЛ ПИСЬМО» + «КОМБИНИРОВАНИЕ КОЛЬЦА ВЫШЕ» (не забывая «ANGSTROM SIGN»), который я считаю кошмаром. (И как «LATIN CAPITAL LETTER A» + «КОМБИНИРОВАНИЕ КОЛЬЦА ВЫШЕ» + «КОМБИНИРОВАНИЕ КЕДИЛЫ» должно сравниваться с «ЛАТИНСКОЙ КАПИТАЛОМ ПИСЕМ» + «КОМБИНИРОВАННОЙ КЕДИЛОМ» + «КОМБИНИРОВАНИЕ КОЛЬЦА ВЫШЕ»). * Настоящая * трудность, однако, заключается в том, что реальные языки сложны: мой любимый пример заключается в том, что нижняя версия «МАСС» на немецком языке - это «Maß» или «Mass», в зависимости от того, какое слово она есть. –

2

Не зная кодировку, вы не можете этого сделать. Я возьму один пример, используя символы с французским акцентом и два разных кодировки: cp850 используется как символ OEM для окон в западной европейской зоне, а также известный iso-8859-1 (также известный как latin1, не очень отличный от win1252 ansi персонаж набор для окон)).

  • в cp850, 0x96 является 'û', 0xca является '╩', 0xea является 'Û'
  • в latin1, 0x96 не является печати (*), 0xca является 'Ê', 0xea является 'ê'

так, если строка закодирован cp850, 0xea должен быть таким же, как 0x96, а 0xca - другим символом

, но если строка кодируется латинским цветом, 0xea должна быть такой же, как 0xca, 0x96 является контрольным ch aracter

Вы можете найти похожие примеры с другими кодировками iso-8859-x, я говорю только о языках, которые я знаю.

(*) в CP1252 0x96 является '–' Юникода символ U + 2013, не связанные с 'ê'

Смежные вопросы