Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Русские буквы


Автор: TwiSteR 16.6.2005, 00:52
Доброго времени суток всем,
Имеется нужда добиться русских букв в stdout
Отсюда How to ???

Автор: chaos 16.6.2005, 06:42
на сколько я понимаю тебе надо перед вывдодм текста в стдоут конвертнуть из одной кодировки в другую

почитай про транслитерацию tr

Автор: Ivan Kolesnikov 16.6.2005, 07:05
Скорее всего программируешь под Windows, все дело в том, что в консоле кодировка oem866, а ты пишешь наверное под Win1251. Выхода 2: или пиши под oem866 или если нужно получить просто понятное русское сообщение в консоле перенаправляй весь вывод в файл:
Код

perl script.pl > temp.txt

А проще всего на мой взгляд выучить английский smile

Автор: TwiSteR 16.6.2005, 07:31
Цитата(Ivan @ 16.6.2005, 07:05)
Скорее всего программируешь под Windows

Да

Цитата(Ivan @ 16.6.2005, 07:05)
А проще всего на мой взгляд выучить английский

Я то его знаю прекрасно (довелось пожить за рубежом), а вот что делать с юзерами ?! smile

Автор: nerezus 16.6.2005, 13:17
> а вот что делать с юзерами ?!
perldoc Tk - самое сложное решение, юзвери-то еще и не консольные ;)

Автор: TwiSteR 16.6.2005, 13:49
Цитата(nerezus @ 16.6.2005, 13:17)
юзвери-то еще и не консольные ;)

Юзверю надо вывести сообщение в консоли после отработки программы, мол так и так выполнено успешно или нет
Добавлено @ 13:53
Цитата(nerezus @ 16.6.2005, 13:17)
perldoc Tk

Сенкс буду изучать

Автор: nerezus 16.6.2005, 15:22
>Юзверю надо вывести сообщение в консоли после отработки программы, мол так и так выполнено успешно или нет
опс, я вроде прогнал... =( в Tk они тоже кракозябликами... =(

Автор: korob2001 16.6.2005, 19:05
Вобщем, что бы больше не возникало такого вопроса написал такой маленьки модуль, который перегоняет строки в DOS кодировку и обратно. Документировать его я не стал, потому как пользоваться им достаточно легко. Внизу сообщения прикреплён файл, качаешь его, распаковываешь, затем распакованный файл Decoder.pm кидай в библиотечный каталог:

Если ты не знаешь какой каталог является библиотечным, то введи в командной строке такую команду:

C:\>perl -V

После чего в самом низу увидишь примерно такие строки:
Цитата

@INC:
     C:/Perl/usr/lib
     C:/Perl/usr/site/lib

Вот это и есть библиотечные каталоги. Теперь кидаешь в один из этих каталогов файл Decoder.pm
С этого момента модуль будет готов к использованию.

Открывем редактор и пишем такую программу:
Код

#!/usr/bin/perl
use Decoder;

# Объявим сразу массив и строку, с кирилицей. Они нам понадобятся для теста.
my @names = qw( Денис Антон Елена Светлана );
$str = "Это просто строка";

# Для начала выведем в STDOUT значение скалярной переменной $str
print to_dos "$str\n";
# Это просто разделитель, на него не обращаем внимания
print "-" x 80, "\n";

# Теперь выведем массив в STDOUT
print to_dos join("\n", @names) . "\n";
# Это просто разделитель, на него не обращаем внимания
print "-" x 80, "\n";

# Если мы результат декодирования сохранить в массиве, то пишем так:
my @dos_names = to_dos \@names;
print "@dos_names\n";
# Это просто разделитель, на него не обращаем внимания
print "-" x 80, "\n";

Если необходимо перевести строку в win1251, то делаем это точно так же, как и в примере выше, только вместо to_dos пишем to_win.

Удачи.

Зы: Предлагаю совместными усилиями доделать этот модуль, т.е. добавить конвертацию строки и в другие известные кодировки, документировать его в POD формате. После чего выложим его в раздел Исходники, который находится рядом с FAQ. Я конечно могу и сам это сделать, но тогда придётся подождать, так как времени сейчас практически нет, потому, пока, могу лишь поувствовать вместе с вами. smile

Автор: TwiSteR 17.6.2005, 17:36
korob2001 Впереди планеты всей !!!
Спасибо !!!

Автор: Vaneska 18.6.2005, 09:18
А можно про модуль по подробней?
что означает вот этот регексп?
Код

$str =~ y/\200-\257\340-\361/\300-\377\250\227/;

Автор: korob2001 19.6.2005, 11:16
Это не регексп, это транслитерация подобная tr///; Здесь сложного ничего нет, транслитерация проходит строку символ за символом и заменяет его на соответствующий, который стоит во второй его части.
Например если есть строка Hello, нам нужно перевести все буквы l, в верхний регистр.:
Код

#!/usr/bin/perl -w
$str =  "Hello";
$str =~ tr/l/L/;
print $str;

Вобщем tr/// и y/// это одно и то же.

Автор: kostofffan 19.6.2005, 22:20
korob2001, а ты бы не мог выложить сюда листинг модуля. А то что-то ваши правила по скачиванию... :(((((((

Автор: korob2001 19.6.2005, 23:04
Цитата

korob2001, а ты бы не мог выложить сюда листинг модуля. А то что-то ваши правила по скачиванию... smile((((((

Пожалуйста:
Код

package Decoder;

require Exporter;
push( @ISA, 'Exporter' );
@EXPORT = qw( to_dos to_win );
@EXPORT_OK = qw();

sub to_win {
    my $str = shift;
    if ( ref( $str ) ) {
         y/\200-\257\340-\361/\300-\377\250\227/ for @$str;
    } else {
         $str =~ y/\200-\257\340-\361/\300-\377\250\227/;
    }
    return (wantarray && ref( $str )) ? @$str : $str;
}

sub to_dos {
    my $str = shift;
    if ( ref( $str ) ) {
         y/\300-\377\250\227/\200-\257\340-\361/ for @$str;
    } else {
         $str =~ y/\300-\377\250\227/\200-\257\340-\361/;
    }
    return (wantarray && ref( $str )) ? @$str : $str;
}

1;

Автор: Vaneska 20.6.2005, 00:39
korob2001, я так понимаю, что "\200" - это код символа, а "-" перечистение, типа 0..9?

Автор: korob2001 20.6.2005, 12:39
Да. Если запустить этот код на выполнение,
Код

#!/usr/bin/perl -w
use strict;
#print "\320" x 15, "\n";
print "\317\320\310\302\305\322 \314\310\320\n";

на выходе получишь строку "ПРИВЕТ МИР!"

Автор: chaos 20.6.2005, 13:06
консольная команда меняющая кодировку на сеанс chcp 1251
chcp выводит текущую кодировку

Автор: korob2001 20.6.2005, 13:16
Ничего не выйдет, попробуй запусти этот код:
Код

#!/usr/bin/perl -w
use strict;
eval { system('chcp 1251') };
print "Привет мир!\n" unless $@;
eval { system('chcp 866') };

Автор: chaos 20.6.2005, 14:19
Цитата(korob2001 @ 20.6.2005, 13:16)
Ничего не выйдет, попробуй запусти этот код:
Код

#!/usr/bin/perl -w
use strict;
eval { system('chcp 1251') };
print "Привет мир!\n" unless $@;
eval { system('chcp 866') };

ну запустил, вот результат:
C:\>test.pl
Текущая кодовая страница: 1251
Привет мир!
Текущая кодовая страница: 866

и на оборот

C:\>test.pl
Текущая кодовая страница: 866
╧ЁштхЄ ьшЁ!
Текущая кодовая страница: 1251

так что все работает

Автор: korob2001 20.6.2005, 15:05
Я так и запускаю, но кирилицы я так и не заметил. smile

Автор: chaos 20.6.2005, 15:16
Цитата(korob2001 @ 20.6.2005, 15:05)
Я так и запускаю, но кирилицы я так и не заметил. smile

или мне домой уже пора идти с работы или чего то я не допонимю, у нас результаты разные или что?

Автор: sharq 21.6.2005, 18:40
korob2001, не хочу растраивать, но такой модуль уже существует - cyrillic.

Код

use strict;
use cyrillic qw/ convert win2koi utf2dos mac2utf dos2mac win2dos utf2win win2utf dos2win mac2dos utf2mac dos2utf/;

my $utf = "Хелло Р’орльд!\n";
print "UTF-8: $utf";

my $dos = utf2dos mac2utf dos2mac win2dos utf2win $utf;
print "DOS: $dos";

my $win = "привет\n";
my $dos2 = win2dos $win;
my $utf2 = win2utf dos2win mac2dos utf2mac dos2utf $dos2;
print "UTF-W: $utf2";
my $dos_ = utf2dos mac2utf dos2mac win2dos utf2win $utf2;
print "DOS: $dos_";

my $koi = win2koi $win;
print $koi;

my $uni = convert('win', 'uni', \$win);
print $uni;


Работает очень хорошо!

Кстати, с подобной проблемой сам сталкивался. smile

Автор: korob2001 21.6.2005, 19:33
sharq - это понятно, просто иногда полезно делать что-нить ручками, да бы развиваться. smile

Автор: sharq 21.6.2005, 20:49
korob2001 согласен. Развиваться всегда надо.

Скажи, как перевестирусские прописные буквы в заглавные, используя рег эксп. Для латиницы - понятно (\L\u), вот для кириллицы - не подходит.
Я эту проблему решил в лоб: через хеш.

Автор: korob2001 21.6.2005, 20:59
sharq - а почему бы для этого не создать отдельный топик??? Ведь человек задал здесь абсолютно другой вопрос. TwiSteR - тебя это тоже касается. smile

sharq - А если по существу, просто подключи use locale, после чего заюзай встроенные функции ucfirst(), uc(), lcfirst(), lc(). Если ты под никсами, use locale может тебе не помочь, тогда подключай POSIX и напрямую укажи с чем ты работаешь. Только в следующий раз создавай отдельный топик, для своего вопроса. Спасибо.

Автор: TwiSteR 21.6.2005, 22:48
korob2001

Да я хотел, но почему-то подумал раз уж тут про так сказать руссификацию завели речь, вот сюда и запостил. Если можешь то раздели тему плиз. smile


Цитата(sharq @ 21.6.2005, 22:13)
используй латинцкий алфавит для названия файлов

Узерам этого не объяснишь, чтобы свои документы сохраняли в латинских именах файлов smile

Автор: korob2001 21.6.2005, 22:56
Цитата

Да я хотел, но почему-то подумал раз уж тут про так сказать руссификацию завели речь, вот сюда и запостил.

Это правила форума, один топик - один вопрос. Не я их придумал, но по идее они верны, так легче найти ответ на вопрос, который уже встречался ранее.
Цитата

Если можешь то раздели тему плиз

Создай новый топик, можешь написать в нём только несколько любых символов, затем я удалю сообщение и перенесу все посты, которые касаются Archive::Zip, в новый топик.

Автор: korob2001 22.6.2005, 00:29
М
 
Тема закрыта

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)