23 сентября 2014 г., 12:48 пользователь Илья Винокуров <[email protected]> написал: > Здравствуйте, Виктор. > > Терминология действительно сильно упрощенная, так как > внутреннее представление строки Perl проще назвать еще одной кодировкой, > с которой нужно работать, чем копаться в кишках.
Не согласен. Термин "кодировка" к этому нельзя применять. Когда речь идёт о кодировке - речь идёт о бинарных данных (байтах). Символы же это не байлы - это элементы, код у которых может быть больше 255. Так же в Perl чётко идеологически разграничены операции над текстом и над бинарными данными. А именно есть операции которые думают что их операнды текст (регэкспы, вывод в файл у которго стоит binmode encoding), есть операции которые думают что их операнды - байты (вывод в файл где нет binmode encoding, функции типа pack). Это всё нельзя уложить в концепцию кодировок. символы vs байты определены здесь http://search.cpan.org/~shay/perl-5.20.1/pod/perlunitut.pod#Text_strings_%28character_strings%29 > > Вот попробуй человеку объяснить зачем нужно для строки в UTF-8 кодировке > делать Encode::decode('UTF-8', $string). А когда говоришь, что у Perl своя > кодировка, > так сразу человек начинает правильно перекодировать строки... А без этой > абстракции человек лезет флаги строкам устанавливать... Может новичку это поможет на ранней стадии только потом помешает. Если бы концепция про кодировки была верная, можно было бы конвертировать между кодировками с помощью Encode::from_to, и вообще не понятно API когда делаются две функции Encode::decode/encode чтобы конвертировать из/в кодировку. > > И такой ход мыслей у многих людей, так что здесь > http://search.cpan.org/~shay/perl-5.20.1/pod/perlunifaq.pod#What%27s_the_difference_between_UTF-8_and_utf8? > Плюнули и согласились: > Okay, if you insist: the "internal format" is utf8, not UTF-8. Не согласен с интерпретацией этого куска документации. На самом деле речь там идёт про что: 1) Есть кодировка "UTF-8" и "utf8". Когда декодируют первую, принимают во внимание то что не все Unicode символы существуют в прикоде. Когда декодируют вторую, это игнорируется, т.е. вторая используется как "кодек" похожий на UTF-8 для произвольных (бинарных !) данных а не текста. 2) Внутрненний формат строки в perl, когда у ней установлен UTF-8 флаг, является не строгим вариантом UTF-8, т.е. в ней могут содержаться вообще не символы, просто набор чисел закодированных в кодек UTF8, не являющийся валидным UTF-8 но с точки зрения перл полностью валидным. например perl -e 'print v100.2000.3000' v100.2000.3000 - это строка из трёх элементов: 100, 2000 и 3000. закодированна этим кодеком. без оглядки на то есть ли в стандарте unicode эти символы. так можно закодировать произвольные числа. т.е. UTF8 как бы используется perl не по назначению. именно поэтому написан этот параграф. > > С почтением, > Илья Винокуров. > > > Mon, 22 Sep 2014 12:58:13 +0400 от Victor Efimov <[email protected]>: > > 22 сентября 2014 г., 12:51 пользователь Илья Винокуров <[email protected]> > написал: >> Здравствуйте, Николай. >> >> Внутри Perl строки хранятся в кодировке, совместимой с UTF-8. Эта >> кодировка >> называется utf8. >> Когда строки вводятся в Perl, их нужно декодировать из различных кодировок >> в >> utf8. >> В том числе нужно декодировать UTF-8 в utf8. >> Если строку нужно вывести из Perl, то эту строку нужно кодировать в >> различные кодировки. >> В том числе нужно кодировать utf8 в UTF-8 >> > > только тут введена какя-то странная терминология, которой на самом деле нет. > > В perl строки не храянятся как набор абстрактных символов. Рассуждения > про их кодировку лучше присекать на корню. > Отличия между utf8 и UTF-8 - вовсе не в этом, а в том что utf-8 более > строкая валидация чем utf8. > > Но в остальном, если в тексте выше заменить "utf8" на "символьная > строка", то будет ок. > >> Этим занимаются функции Encode::encode('UTF-8', $string) и >> Encode::decode('UTF-8', $string). >> >> Text::Iconv - не используйте это, если точно не знаете почему вам нужен >> именно этот модуль. >> >> Концепцию работы с кодировками в Perl я рассказал, >> а вот свой скрипт поправить потрудитесь сами пожалуйста... >> >> PS: Чтобы не возиться в явном виде с перекодированием строк, в перл >> используют >> >> binmode STDIN, ":encoding(console_in)" if -t STDIN; >> binmode STDOUT, ":encoding(console_out)" if -t STDOUT; >> binmode STDERR, ":encoding(console_out)" if -t STDERR; >> >> После этого в STDIN/STDOUT можно читать/писать строки в кодировке utf8 без >> перекодирования... >> >> С почтением, >> Илья Винокуров. >> >> Mon, 22 Sep 2014 01:28:15 +0400 от Nikolay Mishin <[email protected]>: >> >> Привет, MoscowPM, >> тут родился вопрос под win7 (юникс могут быть теже странности, не >> проверял) >> >> #!/usr/bin/env perl >> use utf8; >> use Modern::Perl; >> use Encode::Locale; >> use Encode qw( decode encode from_to); >> use Text::Iconv; >> use Encode::Detect::Detector; >> use Data::Dumper qw( Dumper ); >> >> >> if (-t) >> { >> binmode(STDIN, ":encoding(console_in)"); >> binmode(STDOUT, ":encoding(console_out)"); >> binmode(STDERR, ":encoding(console_out)"); >> } >> >> my $lang = shift or die "Usage: $0 What_is_your_language?\n"; >> my_dump('lang_01',$lang); >> my $converter = Text::Iconv->new( "cp1251", "utf-8"); >> $lang = $converter->convert($lang); >> my_dump('lang_02',$lang); >> $lang = Encode::decode("utf8",$lang); >> my_dump('lang_03',$lang); >> my_dump('lang_04_перл',qq{перл}); >> >> $lang =~ /(perl|перл) (?{print "use Perl or die!!\nИспользуй Перл или >> умри!!";}) /ix;#русский не мачится, почему? >> >> sub my_dump >> { >> my ($name,$var)=@_; >> local $Data::Dumper::Useqq = 1; >> local $Data::Dumper::Indent = 0; >> local $Data::Dumper::Terse = 1; >> print(Encode::Detect::Detector::detect(qq{$lang})." ".qq{\$$name }." >> dump=".Dumper($var)."\n"); >> } >> >> этот же код на гитхабе >> >> https://github.com/mishin/presentation/blob/master/100_regex_4_moscow_pm.pl >> >> моя задача была, чтобы скрипт >> perl 100_regex_4_moscow_pm.pl перл >> читая из консоли слово "перл" находил его в регексе внутри скрипта >> >> вопросы: >> 1) почему, если в консоле >> perl -MEncode::Detect::Detector -E "say >> Encode::Detect::Detector::detect(qq{перл})" >> у меня кодировка ISO-8859-7 >> my $converter = Text::Iconv->new( "cp1251", "utf-8"); >> Text::Iconv ее проглатывает как cp1251 (причем ISO там не проходит) ? >> >> 2)что происходит со строкой здесь >> UTF-8 $lang_02 dump="\320\277\320\265\321\200\320\273" >> $lang = Encode::decode("utf8",$lang); >> UTF-8 $lang_03 dump="\x{43f}\x{435}\x{440}\x{43b}" >> --что такое делает decode? >> я так понимаю - он починивает utf8, но что конкретно >> >> спасибо, хорошей недели!! >> >> >> -- >> С уважением >> Николай Мишин >> >> -- >> Moscow.pm mailing list >> [email protected] | http://moscow.pm.org >> >> >> >> -- >> Moscow.pm mailing list >> [email protected] | http://moscow.pm.org >> > -- > Moscow.pm mailing list > [email protected] | http://moscow.pm.org > > > > -- > Moscow.pm mailing list > [email protected] | http://moscow.pm.org > -- Moscow.pm mailing list [email protected] | http://moscow.pm.org
