Perl, UTF8, Кириллица. Как совместить несовместимое?

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

Аватара пользователя
anterior
Сообщения: 266
ОС: Debian amd64

Perl, UTF8, Кириллица. Как совместить несовместимое?

Сообщение anterior »

Здравствуйте. Есть исходник:

Вариант 1:

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

#!/usr/bin/perl -w
use strict;
use CGI qw/:standard/;
print header(-charset=>'UTF8'),
  start_html('A Simple Example');
print "Входящие параметры: " . b(param('str'))."<br>";
print "Регулярные выражения: " . b(('дмитрий станиславович' =~ /Дмитрий/i? "+": "-"))."<br>";
print "Регистр символов: " . b((uc('дмитрий') eq 'ДМИТРИЙ'? "+": "-"))."<br>";
print "Сравнение строк: " . b(('С' lt 'Я'? "+": "-"))."<br>";
print end_html();

Текст исходника написан на UTF8. Ввожу в браузере https://127.0.0.1/cgi-bin/koitest.pl?str=привет. Получаю:
Входящие параметры: привет
Регулярные выражения: -
Регистр символов: -
Сравнение строк: +


Вариант 2:

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

#!/usr/bin/perl -w
use strict;
use utf8; # <----------------------------
use CGI qw/:standard/;
print header(-charset=>'UTF8'),
  start_html('A Simple Example');
print "Входящие параметры: " . b(param('str'))."<br>";
print "Регулярные выражения: " . b(('дмитрий станиславович' =~ /Дмитрий/i? "+": "-"))."<br>";
print "Регистр символов: " . b((uc('дмитрий') eq 'ДМИТРИЙ'? "+": "-"))."<br>";
print "Сравнение строк: " . b(('С' lt 'Я'? "+": "-"))."<br>";
print end_html();

Текст исходника написан на UTF8. Ввожу в браузере https://127.0.0.1/cgi-bin/koitest.pl?str=привет. Получаю:
Входящие параметры: ГђВїГ‘?ГђВёГђВІГђµГ‘‚
Регулярные выражения: +
Регистр символов: +
Сравнение строк: +


Вариант 3:

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

#!/usr/bin/perl -w
use strict;
use encoding 'utf8'; # <----------------------------
use CGI qw/:standard/;
print header(-charset=>'UTF8'),
  start_html('A Simple Example');
print "Входящие параметры: " . b(param('str'))."<br>";
print "Регулярные выражения: " . b(('дмитрий станиславович' =~ /Дмитрий/i? "+": "-"))."<br>";
print "Регистр символов: " . b((uc('дмитрий') eq 'ДМИТРИЙ'? "+": "-"))."<br>";
print "Сравнение строк: " . b(('С' lt 'Я'? "+": "-"))."<br>";
print end_html();

Текст исходника написан на UTF8. Ввожу в браузере https://127.0.0.1/cgi-bin/koitest.pl?str=привет. Получаю:
Входящие параметры: ГђВїГ‘?ГђВёГђВІГђµГ‘‚
Регулярные выражения: +
Регистр символов: +
Сравнение строк: +


Вариант 4:

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

#!/usr/bin/perl -w
use strict;
use utf8; # <--------------------------
use encoding 'utf8'; # <---------------------------
use CGI qw/:standard/;
binmode(STDIN, ":encoding(utf8)"); # <----------------------
binmode(STDOUT, ":encoding(utf8)"); # <----------------------
print header(-charset=>'UTF8'),
  start_html('A Simple Example');
print "Входящие параметры: " . b(param('str'))."<br>";
print "Регулярные выражения: " . b(('дмитрий станиславович' =~ /Дмитрий/i? "+": "-"))."<br>";
print "Регистр символов: " . b((uc('дмитрий') eq 'ДМИТРИЙ'? "+": "-"))."<br>";
print "Сравнение строк: " . b(('С' lt 'Я'? "+": "-"))."<br>";
print end_html();

Текст исходника написан на UTF8. Ввожу в браузере https://127.0.0.1/cgi-bin/koitest.pl?str=привет. Получаю:
Входящие параметры: ГђВїГ‘?ГђВёГђВІГђµГ‘‚
Регулярные выражения: +
Регистр символов: +
Сравнение строк: +


Как подружить?

ЗЫ:

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

$ locale
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=


ЗЫЗЫ:

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

$ perl -v

This is perl, v5.8.8 built for x86_64-linux-gnu-thread-multi
Спасибо сказали:
Аватара пользователя
gcc
Сообщения: 526
ОС: FreeBSD 8.0 CURRENT

Re: Perl, UTF8, Кириллица. Как совместить несовместимое?

Сообщение gcc »

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

use encoding 'utf8';


я уже не помню где видел, если найду то напишу
Спасибо сказали:
Аватара пользователя
ояб
Сообщения: 107
ОС: FreeBSD

Re: Perl, UTF8, Кириллица. Как совместить несовместимое?

Сообщение ояб »

http://search.cpan.org/~rgarcia/perl-5.10.0/lib/utf8.pm

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

# Change the native bytes of a Perl scalar to/from UTF-8 bytes.
    utf8::encode($string);
    utf8::decode($string);
Спасибо сказали:
Аватара пользователя
ояб
Сообщения: 107
ОС: FreeBSD

Re: Perl, UTF8, Кириллица. Как совместить несовместимое?

Сообщение ояб »

И вобще заявление
Perl, UTF8, Кириллица. Как совместить несовместимое?
попахивает троллингом. Perl и utf8 наиболее совместимы чем например PHP и utf8.
Не в качестве рекламы, а для примера, вот имаджборда на Perl - кодировка utf8 http://2ch.ru/
вот форум, не уступающий по функционалу IPB и phpBB, опять таки Perl + utf8 http://forum.ipse.ru/
Спасибо сказали:
Аватара пользователя
anterior
Сообщения: 266
ОС: Debian amd64

Re: Perl, UTF8, Кириллица. Как совместить несовместимое?

Сообщение anterior »

ояб писал(а):
05.02.2008 17:16
попахивает троллингом. Perl и utf8 наиболее совместимы чем например PHP и utf8.


Смотря насколько кириллицу применять. Мне вот тоже до поры до времени не приходилось сталкиваться с такой проблемой. У меня всё-таки почти заработал по вашим советам пример для utf8, но появились какие-то глюки связанные с взаимодействием юникода и модуля Tie::File. Да и вообще-то не юникод мне на самом деле нужен, а KOI8-R. Программа пишется в KOI8 и результаты должны выводится в KOI8 и файлы сохранятся тоже в такой кодировке. Я сделал почти работающий пример, но приходится 2 раза подряд применять функцию Encode::from_to:

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

#!/usr/bin/perl -w
use strict;
use encoding 'koi8-r';
use Encode;
use open IN => ':encoding(koi8-r)';
use open OUT => ':encoding(koi8-r)';
use CGI qw/:standard/;
binmode(STDIN, ":encoding(utf8)"); # вот эту строчку тоже убирал и изменял на koi8-r, перлу всё равно
binmode(STDOUT, ":encoding(koi8-r)");
binmode(STDERR, ":encoding(koi8-r)");
print header(-charset=>'KOI8-R'),
  start_html('A Simple Example');
my $s = param('str'); # после этой строки если вызвать Encode::is_utf8($s) вернет 1
Encode::_utf8_off( $s ); # а если этого не сделать то на след. строке вылезет ошибка Wide character in...
Encode::from_to( $s, 'utf8', 'koi8-r');
Encode::from_to( $s, 'utf8', 'koi8-r');
print "Входящие параметры: " . b($s)."<br>"; # здесь теперь гуд
print "Регулярные выражения: " . b(('дмитрий станиславович' =~ /Дмитрий/i? "+": "-"))."<br>";
print "Регистр символов: " . b((uc('дмитрий') eq 'ДМИТРИЙ'? "+": "-"))."<br>";
print "Сравнение строк: " . b(('С' lt 'Я'? "+": "-"))."<br>";
warn("Это предупреждение");
print end_html();


И вот такой результат:
Входящие параметры: привет
Регулярные выражения: +
Регистр символов: +
Сравнение строк: +


Можно как-то обойтись без двойного вызова from_to? И вообще как это упростить всё?
Спасибо сказали:
Аватара пользователя
ояб
Сообщения: 107
ОС: FreeBSD

Re: Perl, UTF8, Кириллица. Как совместить несовместимое?

Сообщение ояб »

Если теобходима перекодировка, то уместней применять Text::Iconv
http://search.cpan.org/~mpiotr/Text-Iconv-1.7/Iconv.pm
Спасибо сказали:
Аватара пользователя
anterior
Сообщения: 266
ОС: Debian amd64

Re: Perl, UTF8, Кириллица. Как совместить несовместимое?

Сообщение anterior »

ояб писал(а):
05.02.2008 18:03
Если теобходима перекодировка, то уместней применять Text::Iconv
http://search.cpan.org/~mpiotr/Text-Iconv-1.7/Iconv.pm


:( Неохота лишний модуль применять

Вот еще пробовал так, указать прагму use bytes но тогда не работают регулярные выражения, сравнение строк, регистр символов. Если одновременно применить use encoding 'koi8-r' и use bytes то тогда текст отображается в виде "\x{00d0}\x{0092}...". Короче какие-то взаимоисключения везде... кажется у меня скоро крыша поедет от этих кодировок
Спасибо сказали:
tba
Сообщения: 48
ОС: Debian, Centos

Re: Perl, UTF8, Кириллица. Как совместить несовместимое?

Сообщение tba »

anterior писал(а):
05.02.2008 17:45
ояб писал(а):
05.02.2008 17:16
попахивает троллингом. Perl и utf8 наиболее совместимы чем например PHP и utf8.


...

Можно как-то обойтись без двойного вызова from_to? И вообще как это упростить всё?


Что вас удерживает на koi8 и чем не устраивает вариант

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

#!/usr/bin/perl -w
use strict;
use warnings;
use CGI qw/:standard/;
use utf8;
use Encode qw/decode/;

binmode STDOUT, ':utf8';

print header(-charset=>'UTF-8'),
  start_html('A Simple Example');
my $s = decode("utf-8", param('str'));
print "Входящие параметры: " . b($s)."<br>";
print "Регулярные выражения: " . b(('дмитрий станиславович' =~ /Дмитрий/i? "+": "-"))."<br>";
print "Регистр символов: " . b((uc('дмитрий') eq 'ДМИТРИЙ'? "+": "-"))."<br>";
print "Сравнение строк: " . b(('С' lt 'Я'? "+": "-"))."<br>";
warn("Это предупреждение");
print end_html();


?
Спасибо сказали: