Pull to refresh

Comments 21

Ну и ещё одно дополнение: одной только кодировкой Unicode проблему локализации не решить.
Типичный пример: для сравнения двух подстрок на естественных яызках обычно обе подстроки приводят к одному регистру. Но, например, в арабском регистров как таковых нет, но на 28 букв приходится 72 символа (так как начертание буквы зависит от соседних букв, чтобы получилась непрерывная вязь). Да и в европейских языках возможны «подставы», если, например, поставили ударение.
Широко распространенных универсальных библиотек, которые бы позволяли работать с любыми языками, насколько я знаю пока нет.
Типичный пример: для сравнения двух подстрок на естественных яызках обычно обе подстроки приводят к одному регистру.

В стандарте юникода для этого есть операция case folding, ей и надо пользоваться.
Типичный пример: для сравнения двух подстрок на естественных яызках обычно обе подстроки приводят к одному регистру.


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

Для сравнения подстрок существуют нормализованные формы. Это НЕ lowercase/uppercase.

Широко распространенных универсальных библиотек, которые бы позволяли работать с любыми языками, насколько я знаю пока нет.

userguide.icu-project.org/collation
Для сравнения подстрок существуют нормализованные формы. Это НЕ lowercase/uppercase.

В нормализованных формах разные регистры остаются разными регистрами. Для регистронезависимого сравнения следует использовать обе операции — и нормализацию, и lowercase. Насчет порядка затрудняюсь, но, кажется, можно использовать любой.
Эм. lowercase использовать не надо, нужно нечто умнее, хотя бы из ICU. Процитирую кусок из первой ссылки.

Consider that the uc("σ") and uc("ς") are both "Σ", but lc("Σ") cannot possibly return both of those.

Дополнительно,
Consider that Unicode::Collate::->new(level => 1)->eq(«d», "ð") is true, but Unicode::Collate::Locale->new(locale=>«is»,level => 1)->eq(«d», " ð") is false. Similarly, «ae» and "æ" are eq if you don’t use locales, or if you use the English one, but they are different in the Icelandic locale
Unicode::Collate перлоспецифично, явление — нет.
Хм, а в .NET все еще плачевнее — "ς".ToUpperInvariant() возвращает "ς" вместо "Σ".

Интересно, есть ли подобный контрпример к операции uppercase?

надо использовать fc, то есть case folding, о чем и написано парой комментов выше.

На счет перла, подскажите, плз. Вот такой ворнинг:

" Wide character in print at "

И вот такие кульбиты:

Према психоаналитичкој теорији Ја представља једну од три инстанце психичког апарата (Ја, Оно и Над Ја). У динамици психичког живота Ја је

=============

Я и гуглил, и все что можно перепробовал.

Кроме, Unicode::Collate о котором только что узнал :)
Это значит, что строка кодирована во внутреннем формате перла.
Для устранения этих проблем есть модуль Encode.
Пример (исходник сохраняете в utf8):

use strict;
use warnings;
use Encode;

my $str = "бла-бла";
print $str; # тут будет всё нормально

$str = Encode::decode_utf8($str); # переводим строку из utf8 во внутренний формат перла
print $str; # упс! Wide character in print

$str = Encode::encode_utf8($str); # переводим строку обратно в utf-8
print $str; # бинго
Спасибо, ksusha

Если вот так:

mysite.ru/cgi-bin/script.pl

То никаких проблем с кодировкой.

А если вот так:

<iframe src="http://mysite.ru/cgi-bin/script.pl" frameborder="0" width="900" height="200" ></iframe>

То получается: " Wide character in print at "

Я уже не знаю куда копать :)
Отлично! С новым осмыслением перечитал документацию к своему языку программирования про работу с многобайтными символами. Теперь всё стало на свои места.
>На самом деле любая строка в Javascript кодирована в UTF-8.
На самом деле, в UTF-16.
alert(decodeURIComponent("%F0%90%80%81").length)
Заодно, проверка верстки хабра
test
На самом деле, в Javascript символ — это некоторая абстракция, которую невозможно преобразовать в число иначе как явным процессом кодирования. Это как раз тот самый крайне редкий случай, когда мы работаем с текстом без кодировки.
Системы, передающие друг другу информацию всегда должны указывать рабочую кодировку. Сайт например говорит браузеру, что он отдает информацию в UTF-8.

Вот тут интересно: а как сайт скажет браузеру, как декодировать информацию о том, что информация от сайта приходит в UTF-8?
В ASCII (так как она совместима со всеми кодировками или практически со всеми) используя символы с кодами 0..127
о, и в самом деле. спасибо за просвещение.
Sign up to leave a comment.

Articles