Pull to refresh

Comments 6

один экземпляр Char представляет один символ Юникода

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

Бессмертный ответ на stackoverflow предостерегает нас от таких глупостей. Это описано в стандарте.

Вообще, здесь нужно думать о том, как поставлена задача. Мне сложно представить, ЗАЧЕМ вообще нужно конвертировать юникодную строку в ASCII. И не надо про создание валидного идентификатора/имени пользователя: есть способы гораздо лучше. Хотя это лишь моё мнение.
Возможность использования суррогатных пар — это единственное различие между UTF-16 и UCS-2

Это — разница между «UTF-16, определённом на UCS-4» и «UTF-16, определённом на UCS-2» (который иногда ради краткости называют UCS-2). Разница — в том, что UTF — encoding, а UCS — charset. Впрочем, в терминологии .NET всё может быть по-другому.

UCS-4 и UTF-32 полностью решают эту проблему тем, что у них доступен более широкий диапазон значений: каждый символ занимает 4 байта, и этого хватает всем и каждому.

UCS-4 — charset, UTF-32 — encoding, это — 2 разные вещи. В UCS-4 нет байтов. Вообще. Потому, что это — набор символов, которым присвоены номера. А UTF-32 — правило «давайте запишем этот набор его номерами по порядку, добавив нули спереди, в big/little-endian порядке (строго говоря, encoding'а UTF-32 без указания порядка байтов нет)».

Суррогатные пары — это головная боль, ведь это значит, что строка, которая состоит из 10 символов, на самом деле может содержать от 10 до 5 включительно «настоящих» символов Юникода.

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

Должно ли ваше приложение рассматривать две строки, содержащие литеру «á» с ударением, но в одной представленную двумя символами, а во второй одним, как равные, или как разные?


Вообще — да. Если пишется приложение с поддержкой юникода не для «галочки». Без нормализации пользы от юникода немного.
> В UCS-4 нет байтов. Вообще.

За исключением случая, когда под UCS-4 понимают UTF-32, но тогда нельзя сказать «UTF-32 и UCS-4».
Большое спасибо за комментарий!

Попробую ответить вместо Дж. Скита на некоторые ваши утверждения.

1.
Либо половину символа Юникода по другой терминологии.

Совершенно верно — именно об этом повествует раздел «Суррогатные пары»

2.
Ну и не до конца понятно, зачем нам знать, 10 или 5 символов в строке?

Могу сходу предложить несколько ситуаций, например, выборка подстроки из строки по индексу (может «порвать» суррогатную пару), переворот строки и т.д.

3.
Вообще — да. Если пишется приложение с поддержкой юникода не для «галочки».

С одной стороны — безусловно согласен. С другой — если бы я весь свой код писал с полной и правильной поддержкой Юникода, то я, пожалуй, до сих пор писал бы своё первое приложение. В этой статье Скит как раз намекает о том, что в большинстве случаев не надо учитывать все эти особенности, так как шанс того, что, к примеру, некий пользователь сайта введёт в текстовое поле символы, «необходимые в» суррогатной паре, крайне мал.
> например, выборка подстроки из строки по индексу (может «порвать» суррогатную пару), переворот строки и т.д.

Нам не будет легче, если выборка разорвёт глиф (оторвёт все/половину комбинирующие элементы, например) или оторвёт RTL mark. К перевороту это тоже относится. Символ — слишком абстрактная вещь, зачастую нам нужны глифы.

>С одной стороны — безусловно согласен. С другой — если бы я весь свой код писал с полной и правильной поддержкой Юникода, то я, пожалуй, до сих пор писал бы своё первое приложение.

На практике достаточно привести к одной форме все входящие данные и к другой — все выходящие. Это стандартные функции.

>шанс того, что, к примеру, некий пользователь сайта введёт в текстовое поле символы, «необходимые в» суррогатной паре, крайне мал.

Если пользователь из восточной Азии, то шанс на порядки увеличивается. Конечно, можно считать юникод панъевропейской кодировкой, но даже в этом случае немало нетривиальных случаев (как раз с диакритикой, диграфами и нормализациями). К счастью, с ними не настолько сложно работать. Поддержка Юникода нетривиальна, но в ней нет ничего сверхестественного.
«Ещё несколько лет назад считалось, что все символы «влезут» в диапазон между 0 и 2^(16-1)»
перенесите из степени единичку :)
Большое спасибо, поправил. Моя вина, в оригинале было "...in the range 0 to 2^16-1 would be required,...".
Sign up to leave a comment.

Articles