Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> UC/LC and UTF-8, UC/LC and UTF-8 
:(
    Опции темы
mastercz
Дата 11.1.2010, 08:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



подскажите пожалуйста, как в UTF-8 консоли заставить работать uc()/lc() ?
заранее благодарю за ответ.

Это сообщение отредактировал(а) mastercz - 11.1.2010, 08:25
PM MAIL   Вверх
krypt3r
Дата 11.1.2010, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



Код

use utf8;

Если будет появляться ошибка Wide character in print..., то добавьте, например, строку
Код

binmode STDOUT, ':utf8';

PM MAIL   Вверх
mastercz
Дата 11.1.2010, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



Цитата(krypt3r @ 11.1.2010,  09:14)
Код

use utf8;

Если будет появляться ошибка Wide character in print..., то добавьте, например, строку
Код

binmode STDOUT, ':utf8';

krypt3r  а нельзя как нибудь без

Код

binmode STDOUT, ':utf8';

я, к сожалению не понимаю, зачем  она здесь, на как-то костыль напоминает.
Возможно я ошибаюсь ?

Возможно есть другие функции заменяющие uc/lc для UTF-8...
P.S >Да кстати, perl 5.8.8, UTF-8 local
PM MAIL   Вверх
krypt3r
Дата 11.1.2010, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



Код

use utf8;
use open qw /:std :utf8/;

PM MAIL   Вверх
Pfailed
Дата 11.1.2010, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 22
Всего: 39



Еще как вариант
Код

use encoding 'utf8';

Тогда патчить stdout не нужно.


--------------------
PM MAIL   Вверх
mastercz
Дата 22.1.2010, 08:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



что-то не догоняю. подскажите пожалуйста, как быть  быть с входными данными. Флаг UTF8 из  аргументов не ставиться, как правильно заставить заставить считать перл, что к нему пришли на входе данные в UTF8.
Заранее благодарен за помощь.

Вот тестовый пример..
Код

#!/usr/bin/perl

use strict;
use utf8;
use open qw /:std :utf8/;

#use encoding 'utf8';
#binmode STDOUT, ':utf8';

#use Encode;

use DBI;
use DBD::Pg;
use Devel::Peek;



    my $dbh = DBI->connect("dbi:Pg:dbname=test", "test", "", { AutoCommit=>"0",RaiseError=>"1" });
       $dbh->{pg_enable_utf8} = 1;
       my $arg=@ARGV[0];
       my $select="select * from tsttables";
       my $sth=$dbh->prepare($select);
      $sth->execute;
     
    my $i=0;
       while(my @tmp=$sth->fetchrow_array)
         {

                print uc($tmp[0])."\t".uc($tmp[1])."\t"."\n";
                $i++;
        }

    $dbh->disconnect;

  #Encode::_utf8_on($arg);

    print "-->>".uc($arg)."\n";
    print "-->>";
    print Dump($arg)."\n";
  exit;


PM MAIL   Вверх
krypt3r
Дата 22.1.2010, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



Если данные в базе в UTF-8, то попробуйте после коннекта провести запрос
Код

$dbh->do ("SET client_encoding = utf8");

PM MAIL   Вверх
Pfailed
Дата 22.1.2010, 10:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 22
Всего: 39



Или такой вариант:
Код

$dbh->do('SET names utf8');



--------------------
PM MAIL   Вверх
mastercz
Дата 22.1.2010, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет




Ту дело не в Базе Данных, строки к ней можно закомментировать.

Проблема в том что, строка берущаяся в качестве аргумента без флага UTF8.

В реальной задаче данные которые я подаю на вход WEB - скрипта, превращаются в не читаемую хрень еще до записи в базу.

Думаю это не важно, но на всякий случай в реальной задаче это Apache2+ mod_perl2 + mason 1.39 + perl 5.10

PM MAIL   Вверх
krypt3r
Дата 22.1.2010, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



Эм, а это у вас что?
Код

my $arg=@ARGV[0];

Наверно, предполагалось что-то типа
Код

my $arg=$ARGV[0];
# или
my $arg=shift;

PM MAIL   Вверх
mastercz
Дата 22.1.2010, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



Код

my $arg=@ARGV[0]; 
#запись аналогична
my $arg=$ARGV[0];


PM MAIL   Вверх
Pfailed
Дата 22.1.2010, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 22
Всего: 39



Цитата(mastercz @ 22.1.2010,  15:40)
Код

my $arg=@ARGV[0]; 
#запись аналогична
my $arg=$ARGV[0];

С точки зрения перла не аналогична. Первое - это срез массива, а второе элемент массива.
use warnings об этом намекает.


--------------------
PM MAIL   Вверх
mastercz
Дата 25.1.2010, 02:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



Выходные кончились, возвращаюсь к задаче.

Чувствую себя полным бараном но пока не вижу решения даннаой проблемы :(
Неужели ни у кого не работает Web-Perl скрипт полностью под UTF-8.
Мне кажется задачка весьма тривиальна просто я чего-то не догоняю.

Поделитесь пожалуйста опытом, как вы заставляете интерпретатор, понимать что из веб-морды пришли данные 
в UTF-8. Я предполагаю, если я усилием воли подниму флаг на переменную, то проблема исчезнет. Вот только, _utf8_on($arg); внутренняя функция, а как это сделать корректно, я не знаю. И еще, прагма use open qw /:std :utf8/; должна ИМХО работать и над STDIN и на STDOUT почему же в приведенном выше примере аргумент из командной строки не воспринимается как UTF-8. Для наглядности упрощаю вид вышеприведенного примера:
Код

#!/usr/bin/perl

use strict;
use utf8;
use open qw /:std :utf8/;
use Encode;
use Devel::Peek;

  
 my $arg=$ARGV[0];

#Encode::_utf8_on($arg);

print "-->>".uc($arg)."\n";
print Dump($arg)."\n";
exit;


PM MAIL   Вверх
krypt3r
Дата 25.1.2010, 07:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



Цитата

utf8::downgrade снимает флаг со строки
utf8::upgrade выставляет флаг на строку

http://www.nestor.minsk.by/sr/2008/09/sr80902.html
http://xpoint.ru/know-how/Perl/PodderzhkaUnicode
Для юникодизации массива @ARGV запускайте интерпретатор с ключом -CA
Код

$ perl -CA myscript.pl

Added:
Так как этот ключ не работает в самом скрипте, то можно в BEGIN {...} прописать насильную установку utf8-флага для @ARGV - по дефолту у этого массива данный флаг отключен

Это сообщение отредактировал(а) krypt3r - 25.1.2010, 09:19
PM MAIL   Вверх
mastercz
Дата 26.1.2010, 02:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



krypt3r, спасибо за помощь.

Web-скрипт вроде как отчасти заработал.
Я использовал следующую настройку под html-mason

Код

package SetMasonUTF8;
use base qw(HTML::Mason::Plugin);
use warnings;
use strict;
sub start_request_hook {
    my ( $self, $context ) = @_;
    return if $context->request->is_subrequest;
    my $args_ref = $context->args();
    foreach my $arg ( @{$args_ref} ) {
        utf8::is_utf8($arg) || utf8::decode($arg);
    }
    return;
}
1;


Плюс в настройках Apache2
Код

        PerlSetVar MasonPreamble "use utf8;"
        PerlAddVar MasonPlugins "SetMasonUTF8"

Однако почему то DBI  а именно $dbh->errstr   выдает некорректный текст несмотря на 
Код

$dbh->{pg_enable_utf8} = 1;


Получаю что-то вида 
Код

ERROR: Ð½ÐµÐ²ÐµÑ€Ð½Ñ‹Ð¹ входной синтаксис для типа double, точность: ""

Хотя обычный поток данных от DBI идет как нужно.

Да и еще, не врубаюсь почему вместо приведенной надстройки не работает прагма 
Код

use open qw /:std :utf8/;

PM MAIL   Вверх
krypt3r
Дата 26.1.2010, 06:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



А вы уверены, что данные в базе именно в UTF8? Что показывает запрос
Код

dbname=# show server_encoding;

?
Делаете ли в скрипте set client_encoding?

Приведу пример. Кластер PostgreSQL собран с кодировкой WIN1251. Есть скрипт, запускаемый локально на серваке. Локаль консоли - ru_RU.UTF-8.
Код

#!/usr/bin/perl

use strict;
use warnings;
#use diagnostics;
use utf8;
use open qw /:std :utf8/;
use DBI;

$\ = "\n";

my $db = DBI->connect ('DBI:Pg:dbname=mydb', 'postgres', undef, 
  {'RaiseError' => 0});
myexit {'message' => 'Connection error: ' . DBI->errstr, 'code' => -1}
  unless defined $db;
print "Connected";
my $srv_enc = $db->prepare ('SHOW server_encoding');
$srv_enc->execute;
$srv_enc = $srv_enc->fetchrow_arrayref;
print 'Server encoding: ', $srv_enc->[0];
print 'Setting client encoding to UTF-8';
$db->do ('set client_encoding = utf8');
$db->{'pg_enable_utf8'} = 1;
my $cln_enc = $db->prepare ('SHOW client_encoding');
$cln_enc->execute;
$cln_enc = $cln_enc->fetchrow_arrayref;
print 'Client encoding: ', $cln_enc->[0];
my $clients = $db->selectall_hashref ('select id, fio from clients where id = 111 order by 1',
  'id');
myexit {'message' => 'Query failed: ' . $db->errstr, 'code' => -2}
  unless defined $clients;
foreach my $id (keys %$clients) {
  print $id, ', ', $clients->{$id}{'fio'};
  print 'utf8 flag is ', utf8::is_utf8 ($clients->{$id}{'fio'}) 
    ? 'on' : 'off';
}
$db->disconnect;

sub myexit {
  my $arg = shift;
  
  print $arg->{'message'};
  exit $arg->{'code'};
}

Вывод скрипта
Код

Connected
Server encoding: WIN1251
Setting client encoding to UTF-8
Client encoding: utf8
111, Иванов Иван Иванович
utf8 flag is on

Так что если все сделано правильно, на выводе будет все красиво)

Это сообщение отредактировал(а) krypt3r - 26.1.2010, 07:29
PM MAIL   Вверх
mastercz
Дата 28.1.2010, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



krypt3r, я наверно неопределенно выразился ... вот пример, что я имел в виду .
Код

#!/usr/bin/perl
#++++++++++++++++++++++++++++++++++++++++++++++
#++++++++++++++++++++++++++++++++++++++++++++++

use strict;
use utf8;
use Encode;
use open qw /:std :utf8/;
#use encoding 'utf8';

use DBI;
use DBD::Pg;
use Devel::Peek;

    my $dbh = DBI->connect("dbi:Pg:dbname=insurance", "worker", "", { AutoCommit=>"0",RaiseError=>"0" });
    $dbh->{pg_enable_utf8} = 1;
    my $arg=$ARGV[0];

    my $select="select * from ppols";

    my $sth=$dbh->prepare($select);
       $sth->execute;

    while(my @tmp=$sth->fetchrow_array)
        {

                print "-->>".uc($tmp[1])."\n";
                print "-->>".Dump($tmp[1])."\n";
        }

    $sth->finish;

     $select="select  from ppols";
            $sth=$dbh->prepare($select);
            $sth->execute;

           if ($dbh->err)
                {
                        print "-->>".$dbh->errstr."\n";
                        print "-->>".Dump($dbh->errstr)."\n";
                }
        $sth->finish;

         $dbh->disconnect;


exit;



на выходе получаю в следующие 
Код

# ./base_utf2.pl
-->>МУЖСКОЙ
SV = PV(0x8c8d200) at 0x8c7b880
  REFCNT = 1
  FLAGS = (POK,pPOK,UTF8)
  PV = 0x8beaec0 "\320\274\321\203\320\266\321\201\320\272\320\276\320\271"\0 [UTF8 "\x{43c}\x{443}\x{436}\x{441}\x{43a}\x{43e}\x{439}"]
  CUR = 14
  LEN = 16
-->>
-->>ЖЕНСКИЙ
SV = PV(0x8c8d1f0) at 0x8c7b840
  REFCNT = 1
  FLAGS = (POK,pPOK,UTF8)
  PV = 0x8beaea8 "\320\266\320\265\320\275\321\201\320\272\320\270\320\271"\0 [UTF8 "\x{436}\x{435}\x{43d}\x{441}\x{43a}\x{438}\x{439}"]
  CUR = 14
  LEN = 16
-->>
DBD::Pg::st execute failed: ERROR:  ошибка синтаксиса в или рядом "from"
LINE 1: select  from pols
                ^ at ./base_utf2.pl line 35.
-->>ERROR:  Ð¾Ñ�ибка Ñ�инÑ�акÑ�иÑ�а в или Ñ�Ñ�дом "from"
LINE 1: select  from pols
                ^
SV = PV(0x8c8d1a0) at 0x8c7ba00
  REFCNT = 1
  FLAGS = (TEMP,POK,pPOK)
  PV = 0x8cb61d8 "ERROR:  \320\276\321\210\320\270\320\261\320\272\320\260 \321\201\320\270\320\275\321\202\320\260\320\272\321\201\320\270\321\201\320\260 \320\262 \320\270\320\273\320\270 \321\200\321\217\320\264\320\276\320\274 \"from\"\nLINE 1: select  from pols\n                ^"\0
  CUR = 113
  LEN = 116
-->>


Т. е. ошибка пришедшая от DBI 
Код
$dbh->errstr
 почемуто не имеет флага UTF8.
PM MAIL   Вверх
krypt3r
Дата 28.1.2010, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 9.6.2009

Репутация: 2
Всего: 16



Код

SET lc_messages = 'en_US.utf8';

поэкспериментируйте со значением.
PM MAIL   Вверх
mastercz
Дата 29.1.2010, 03:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



кажется нашел, проблема в модуле DBВ::Pg (2.8.7-1) от в сборке от debian lenny
поставил из CPAN текущую  версию и ... о чудо ... проблема исчезла, вот только не хороше это когда не из коробки :(

krypt3r, еще раз спасибо за помощь. 

P.S. Тему пока не закрываю. Закрою после окончательного тестинга скрипта, ежели ничего больше не всплывет.

Это сообщение отредактировал(а) mastercz - 29.1.2010, 03:02
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0628 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.