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


Автор: alezzz 15.4.2011, 11:05
Получаю ответ на LWP::Simple get. Ответ в виде XML, и в нем есть кирилица в utf8. Делаю encode И получаю
Цитата

Cannot decode string with wide characters at C:/Perl/lib/Encode.pm line 174.

Пробовал регуляркой вырезать только нужный текст из XML  и его уже перекодировать, но тоже самое.
декодирую так:
Код

my $fromutf8 = encode("cp1251", decode("utf8", $content));

Автор: arto 15.4.2011, 11:41
# GET "http://forum.vingrad.ru/index.php?showtopic=327136" | perl -MEncode=encode,decode -lne 'encode("cp1251", decode("utf8", $_)) =~ m#<title>.+?</title>#smi && print $&'
<title>VPF::Ошибка encode при декодировании из utf8 - Форум программистов</title>

вы уверены в утфности текста?

Автор: IceSunrise 15.4.2011, 11:47
alezzz,  ошибка возникает при декодировании
Это должно работать, если в $content действительно utf8
Код

$octets = encode_utf8($content);
from_to($octets, 'utf-8', 'cp1251');


Если не сработает, запостите сюда дамп переменной $content до перекодирований. Вот так
Код

use Data::Dumper;
print Dumper($content);

Автор: alezzz 15.4.2011, 12:06
Цитата(arto @  15.4.2011,  11:41 Найти цитируемый пост)
вы уверены в утфности текста?

да, сайт возвращает XML с кирилицей в утф

Я пробовал сделать принт до декодирования, получил такое:
Цитата

Wide character in print at mor.cgi line 17


сам контент
Код

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="
http://www.w3.org/2001/XMLSchema" xmlns="http://morpher.ru/webservices/">
  <string>╨Я╤А╨╛╨│╤А╨░╨╝╨╝╨░ ╨╜╨╡ ╨╝╨╛╨╢╨╡╤В ╨┐╤А╨╛╤Б╨║╨╗╨╛╨╜╤П╤В╤М ╤Н╤В╨╛ ╤Б╨╗╨
╛╨▓╨╛╤Б╨╛╤З╨╡╤В╨░╨╜╨╕╨╡.</string>
</ArrayOfString>

Автор: gcc 15.4.2011, 12:31
http://forum.vingrad.ru/forum/topic-282078/hl/utf8/index.html
http://forum.vingrad.ru/forum/topic-274374/hl/utf8/15.html

Добавлено @ 12:34
для MVC Catalyst пытались сделать, чтобы оно не сбивалось в любом случае!
http://search.cpan.org/~bobtfish/Catalyst-Plugin-Unicode-Encoding-1.1/lib/Catalyst/Plugin/Unicode/Encoding.pm

http://cpansearch.perl.org/src/BOBTFISH/Catalyst-Plugin-Unicode-Encoding-1.1/lib/Catalyst/Plugin/Unicode/Encoding.pm
Код

            for ( ref($value) ? @{$value} : $value ) {
                # N.B. Check if already a character string and if so do not try to double decode.
                #      http://www.mail-archive.com/[email protected]/msg02350.html
                #      this avoids exception if we have already decoded content, and is _not_ the
                #      same as not encoding on output which is bad news (as it does the wrong thing
                #      for latin1 chars for example)..
                $_ = Encode::is_utf8( $_ ) ? $_ : $enc->decode( $_, $CHECK );
            }



тут http://www.mail-archive.com/[email protected]/msg02350.html очень активно обсуждали
там Bill Moseley написал

Автор: arto 15.4.2011, 12:36
url?

Автор: alezzz 15.4.2011, 13:16
http://morpher.ru/WebServices/Morpher.aspx

вот пример:
Код

use strict;
use URI::Escape;
use Encode;
use LWP::Simple;
 
print morpher("яблоко");

sub morpher{ 
    my $string = shift || $_; 
    my $utfstring = encode("utf8", decode("cp1251", $string));
    my $encode = uri_escape($utfstring);
    my $content = get("http://morpher.ru/Webservices/Morpher.asmx/GetForms?s=$encode");
    my $fromutf8 = encode("cp1251", decode("utf8", $content));
    my $words;
    while ($fromutf8 =~ /<string>(.*?)<\/string>/g){
        $words .= $1 . ",";
    }
    return $words;
}


и еще, дома работает без проблем, на работе не хочет, кроме WinXP/Win 7 не вижу разницы.

Автор: arto 15.4.2011, 13:42
perl -v ?

у меня работает нормально

Автор: alezzz 15.4.2011, 14:06
Цитата(arto @  15.4.2011,  13:42 Найти цитируемый пост)
perl -v ?

This is perl, v5.10.0 built for MSWin32-x86-multi-thread
(with 5 registered patches, see perl -V for more detail)
Цитата(arto @  15.4.2011,  13:42 Найти цитируемый пост)
у меня работает нормально

вот в этом и проблема, пытаюсь понять что не так. Еще:
работает - файрвол отключен
не работает - файрвол включен, но get отдает контент
работает и не работатет на разных компьютерах, перл одинаковый

Автор: arto 15.4.2011, 14:44
проверьте, на чем ломается:

perldoc Encode | less -p "Handling Malformed Data"

Автор: alezzz 15.4.2011, 20:12
Решил проблему, поменял LWP::Simple на LWP::UserAgent (когда гуглил что-то такое видел, но не обратил сразу внимания). 
Вобщем такие наблюдения: брал контент из $content->content и $content->decoded_content, если их вывести принтом то внешне ничем не отличаются, только на $content->decoded_content появляется "Wide character in print at...", зато длины строк если посмотреть через length() отличаются. 
Отправил на encode $content->content, работает нормально. 
Непонятно, функции is_utf8, _utf8_on, _utf8_off из Encode реализованы? Ругается "Undefined subroutine &main::is_utf8 ..."

Автор: arto 16.4.2011, 11:24
импортируйте

Автор: alezzz 16.4.2011, 11:39
Цитата(arto @  16.4.2011,  11:24 Найти цитируемый пост)
импортируйте

Точно smile
$flag = Encode::is_utf8($string);
Спасибо.

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