perl+utf8+STDIN (некорректная работа некоторых функций (reverse))

Модератор: Модераторы разделов

Аватара пользователя
Phobos
Сообщения: 87
ОС: Debian GNU/Linux Lenny

perl+utf8+STDIN

Сообщение Phobos »

Доброго времени суток. Проблема в следующем: perl (вернее не весь perl, а только некоторые его функции, такие как reverse, tr/// и некоторые другие) некоректно работает с кириллическими символами, причем только с теми, которые поступают с stdin, в частности:

Код: Выделить всё

 #!/usr/bin/perl -w

use utf8;

$s = "превед";
print("$s\n" . reverse($s) . "\n\n");

while (<>) {
      chomp;
      print(reverse . "\n");
}

Результат:

Код: Выделить всё


phobos@zeus:~/just-for-fun/perl$ ./test.pl
Wide character in print at ./test.pl line 6.
превед
деверп

qwerty
ytrewq
123456
654321
превед
´евеЀѿÐ
какдела
°ледкакÐ

прямо даже и не знаю в чем дело, "Programming Perl" Ларри Уола и гугл говорят что use utf8 достаточно для корректной работы с уникодными строками.

ps В терминале (rxvt-unicode) никаких проблемм с юникодом нет, все отображается корректно, Debian Etch, perl v5.8.8,
локаль:

Код: Выделить всё


LANG=en_US.UTF-8
LC_CTYPE=ru_RU.UTF-8
LC_NUMERIC=POSIX
LC_TIME=POSIX
LC_COLLATE=POSIX
LC_MONETARY=POSIX
LC_MESSAGES=POSIX
LC_PAPER=POSIX
LC_NAME=POSIX
LC_ADDRESS=POSIX
LC_TELEPHONE=POSIX
LC_MEASUREMENT=POSIX
LC_IDENTIFICATION=POSIX
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: perl+utf8+STDIN

Сообщение sash-kan »

см. опцию -C (man perlrun)
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
tba
Сообщения: 48
ОС: Debian, Centos

Re: perl+utf8+STDIN

Сообщение tba »

Phobos писал(а):
05.04.2007 19:26
Доброго времени суток. Проблема в следующем: perl (вернее не весь perl, а только некоторые его функции, такие как reverse, tr/// и некоторые другие) некоректно работает с кириллическими символами, причем только с теми, которые поступают с stdin, в частности:
...


Прочитай perluniintro, perlunicode - там все подробно описывается. Вкратце, перл рассматривает все как октеты(octet). Для того, чтобы он правильно обрабатывал данные, полученые со stdin и выводил правильно в stdout, надо ему об этом сказать

Код: Выделить всё

#!/usr/bin/perl -w

use utf8;
use Encode qw/encode decode/;

$s = "превед";
print("$s\n" . reverse($s) . "\n\n");

while (<>) {
      my $newline = decode('UTF-8', $_);
      chomp $newline;
      print(encode("UTF-8", reverse($newline)) , "\n");
}


А если совсем правильно :) (чтобы warning "Wide character..." не вылазил), надо первый "превед" выводить так

Код: Выделить всё

print(encode("UTF-8","$s\n" . reverse($s) . "\n\n"));


P.S. Ещё полезная ссылка (собсно выше - это мой вольный ее перевод )) http://www.catalystframework.org/calendar/2006/21
Спасибо сказали:
Аватара пользователя
Phobos
Сообщения: 87
ОС: Debian GNU/Linux Lenny

Re: perl+utf8+STDIN

Сообщение Phobos »

ок, спасибо, все прочитаю, думаю разберусь :)
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: perl+utf8+STDIN

Сообщение v04bvs »

Там вроде надо режим utf8 на STDIN и STDOUT поставить, примерно так же как ставится bin, уже точно не помню. Но с юникодом в перле страшно :( как в винде, хотели как лучше для пользователя, получился тихий ужас.
Спасибо сказали:
tba
Сообщения: 48
ОС: Debian, Centos

Re: perl+utf8+STDIN

Сообщение tba »

v04bvs писал(а):
06.04.2007 01:41
Там вроде надо режим utf8 на STDIN и STDOUT поставить, примерно так же как ставится bin, уже точно не помню. Но с юникодом в перле страшно :( как в винде, хотели как лучше для пользователя, получился тихий ужас.


Все нормально в перле с юникодом! Нужно лишь пользоваться правильно :)
Спасибо сказали:
beholder
Сообщения: 29

Re: perl+utf8+STDIN

Сообщение beholder »

tba писал(а):
06.04.2007 00:40

Код: Выделить всё

while (<>) {
      my $newline = decode('UTF-8', $_);
      chomp $newline;
      print(encode("UTF-8", reverse($newline)) , "\n");
}

Зачем такие сложности? binmode для этого есть:

Код: Выделить всё

use utf8;

binmode(STDIN, ':utf8');
binmode(STDOUT, ':utf8');

$s = "превед";
print("$s\n" . reverse($s) . "\n\n");

while (<>) {
  chomp;
  print(reverse . "\n");
}
Спасибо сказали:
beholder
Сообщения: 29

Re: perl+utf8+STDIN

Сообщение beholder »

v04bvs писал(а):
06.04.2007 01:41
Но с юникодом в перле страшно :( как в винде, хотели как лучше для пользователя, получился тихий ужас.

По-моему, с юникодом в Перле всё нормально. Если брать скриптовые языки, то лучше нигде нет, imho (даже в Питоне).
Спасибо сказали:
tba
Сообщения: 48
ОС: Debian, Centos

Re: perl+utf8+STDIN

Сообщение tba »

beholder писал(а):
06.04.2007 12:41
Зачем такие сложности? binmode для этого есть:

Код: Выделить всё

use utf8;

binmode(STDIN, ':utf8');
binmode(STDOUT, ':utf8');

$s = "превед";
print("$s\n" . reverse($s) . "\n\n");

while (<>) {
  chomp;
  print(reverse . "\n");
}


Согласен, протупил. binmode действительно проще. Впрочем автору топика(как и мне )) про юникод в перле почитать не помешает :)
Спасибо сказали: