Когда использовать формы нормализации Unicode NFC и NFD?

Часто задаваемые вопросы по нормализации Unicode включает следующий абзац:

Программы всегда должны сравнивать канонически эквивалентные строки Unicode как равные... Стандарт Unicode предоставляет четко определенные формы нормализации, которые можно использовать для этого: NFC и NFD.

и продолжается...

Выбор того, что использовать, зависит от конкретной программы или системы. NFC — лучшая форма для обычного текста, поскольку она более совместима со строками, преобразованными из устаревших кодировок. ... NFD и NFKD наиболее полезны для внутренней обработки.

Мои вопросы:

Что делает NFC лучшим для «общего текста». Что определяет «внутренняя обработка» и почему ее лучше оставить для NFD? И, наконец, независимо от того, что является «лучшим», взаимозаменяемы ли две формы, если две строки сравниваются с использованием одной и той же формы нормализации?


person Jesse Hallam    schedule 13.04.2013    source источник
comment
«NFC — лучшая форма для обычного текста, поскольку она более совместима со строками, преобразованными из устаревших кодировок. ... NFD и NFKD наиболее полезны для внутренней обработки». несколько ложные заявления. Хотя устаревшие строки могут иметь форму, которая при преобразовании в Unicode находится в форме NFC, для дальнейшего обслуживания (код всегда заканчивается использованием в непредвиденных условиях) будет лучше, если вы выполните преобразование в NF[CD] явно.   -  person ninjalj    schedule 13.04.2013


Ответы (2)


Часто задаваемые вопросы несколько вводят в заблуждение, начиная с использования «должен», за которым следует непоследовательное использование «требования» об одном и том же. Сам стандарт Unicode (цитируется в FAQ) является более точным. По сути, вы не должны ожидать, что программы будут рассматривать канонически эквивалентные строки как разные, но вы также не должны ожидать, что все программы будут рассматривать их как идентичные.

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

Например, U+0387 ГРЕЧЕСКИЙ АНО ТЕЛЕЯ (·) определяется как канонический эквивалент U+00B7 СРЕДНЯЯ ТОЧКА (·). Это было ошибкой, так как символы действительно отличаются друг от друга и должны отображаться по-разному и обрабатываться по-разному. Но уже слишком поздно это менять, так как эта часть Unicode высечена в камне. Следовательно, если вы конвертируете данные в NFC или иным образом отбрасываете различия между канонически эквивалентными строками, вы рискуете получить неправильные символы.

Если вы не выполняете нормализацию, вы рискуете. Например, буква «ä» может отображаться как один символ Юникода U+00E4 СТРОЧНАЯ ЛАТИНСКАЯ БУКВА A С ДИЭРЕЗИСОМ или как два символа Юникода U+0061 СТРОЧНАЯ ЛАТИНСКАЯ БУКВА A U+0308 КОМБИНИРОВАНИЕ ДИЭРЕЗИСА. В основном это будет первая, то есть предварительно составленная форма, но если это последняя, ​​и ваш код проверяет данные, содержащие «ä», используя только предварительно составленную форму, то он не обнаружит последнюю. Но во многих случаях вы не делаете таких вещей, а просто сохраняете данные, объединяете строки, печатаете их и т. д. Тогда есть риск, что два представления приведут к несколько разным рендерингам.

Также имеет значение, передает ли ваше программное обеспечение данные о символах другому программному обеспечению. Получатель может ожидать, из-за наивных неявных предположений или сознательно и задокументированным образом, что его ввод нормализуется.

person Jukka K. Korpela    schedule 13.04.2013
comment
Одним из мест, где U+0061 LATIN SMALL LETTER A U+0308 COMBINING DIAERESIS будет способом выразить «ä», будут имена файлов Max OS X, для которых требуется определенная версия NFD. - person hippietrail; 13.04.2013
comment
@hippietrail это где-то задокументировано? - person Keith4G; 09.01.2014
comment
@ Keith4G: На SO должны быть вопросы об этом. Позвольте мне взглянуть на вас. Я не фанат Mac, но несколько лет назад я кое-что сделал для чтения разделов Mac для развлечения и столкнулся с этим. - person hippietrail; 09.01.2014
comment
У меня возникли проблемы с поиском конкретной информации о нормализации OS X. Спасибо - person Keith4G; 09.01.2014

  1. NFC — это общая форма здравого смысла, которую вы должны использовать, ä — это 1 кодовая точка, и это имеет смысл.

  2. NFD хорош для определенной внутренней обработки — если вы хотите выполнять поиск или сортировку без акцента, наличие вашей строки в NFD сделает это намного проще и быстрее. Еще одно использование — создание более надежных кратких заголовков. Это только самые очевидные из них, я уверен, что есть еще много применений.

  3. #P3#
    #P4#
person Esailija    schedule 13.04.2013
comment
Что касается 3, я не думаю, что это всегда так. Например. (из Википедии) строка 1 содержит U+212B (знак ангстрема Å), строка 2 содержит U+0041 U+030A (латинская буква A и объединяющее кольцо над °). В NFD они эквивалентны, но в NFC строка 2 преобразуется в U+00C5 (шведская буква Å), поэтому они не эквивалентны. Мне кажется, что NFD — самый безопасный выбор. en.wikipedia.org/wiki/Unicode_equivalence#Normal_forms - person Aurimas; 17.12.2013
comment
@Aurimas это с веб-сайта Unicode unicode.org/reports/tr15/tr15-18. html - person Esailija; 17.12.2013
comment
Вы абсолютно правы, я собирался изменить свой комментарий после того, как прочитал больше об этой проблеме. Ключевым моментом здесь является то, что для перехода на NFC вы сначала конвертируете в NFD. - person Aurimas; 17.12.2013