Как правильно отображать HTML-объекты в Perl - PullRequest
1 голос
/ 12 сентября 2011

Я писал веб-сканер, используя PERL, и понял, что было странное поведение, когда я пытался отобразить строку, используя HTML :: Entities :: decode_entities.

Я работал со строками, которые содержат китайские символы и такие строки, как Jìngyè. Я использовал HTML :: Entities :: decode_entities для декодирования китайских символов, что хорошо работает. Однако если строка не содержит китайских символов, строка отображается странно (J ngy ).

Я написал небольшой код для проверки различного поведения на 2 строках.

Строка 1 - это "№ 22, J ngy 3-я дорога, район Jhongshan, город Тайбэй, Тайвань 10466", а строка 2 - "104 Тайвань, город Taipei Jhongshan District J ngy 3-я дорога 20 號".

Ниже мой код:

print "before: $1\n";
my $decoded = HTML::Entities::decode_entities($1."&#34399");#I add the last character just for testing
print "decoded $decoded\n";
my $chopped = substr($decoded, 0, -1);
print "chopped: $chopped\n";

Вот мои результаты:

до: № 22, J ngy 3-я дорога, район Jhongshan, Тайбэй, Тайвань 10466

расшифровано № 22, Jìngyè 3-я дорога, Jhongshan District, Тайбэй, Тайвань, 10466 號 (правильно)

рубленый: № 22, J ngy 3-я дорога, Jhongshan District, Тайбэй, Тайвань 10466 (неверно)

до: 104 Тайвань Тайбэй Город Jhongshan District J ngy 3-я дорога 20 號

расшифровано 104 Тайвань Тайбэй Город Jhongshan District Jìngyè 3-я дорога 20 correct 號 (правильно)

рубленый: 104 Тайвань Тайбэй Город Jhongshan District Jìngyè 3-я дорога 20 號 (правильно)

Может кто-нибудь объяснить, почему это произошло? И как решить эту проблему, чтобы моя строка отображалась правильно.

Большое спасибо.

Извините, я не прояснил свой вопрос, ниже приведен код, который я написал, где URL http://maps.google.com/maps/place?cid=10931902633578573013:

sub getInfoURLs {
my ($url) = @_;
unless (defined $url){
    print 'URL was not defined when extracting info\n';
    return 0;
}

my $contain_request = LWP::UserAgent->new->get($url);
if($contain_request -> is_success){
    my $contain_content = $contain_request -> decoded_content;

    #store address
    if ($contain_content =~ m/$address_pattern/i){
        print "before: $1\n";
        my $decoded = HTML::Entities::decode_entities($1."&#34399");
        print "decoded $decoded\n";
        my $chopped = substr($decoded, 0, -1);
        print "chopped: $chopped\n";
        #unicode conversion
        #store in database            
    }
 }
}

1 Ответ

2 голосов
/ 12 сентября 2011

Во-первых, всегда используйте use strict; use warnings; !!!

Проблема в том, что вы не кодируете свой вывод. Файловые дескрипторы могут передавать только байты, но вы передаете декодированный текст.

Perl выдаст UTF-8 (-ish), когда вы пропустите что-то, что явно не так. chr(0x865F) явно не байт, поэтому:

$ perl -we'print "\xE8\x{865F}\n"'
Wide character in print at -e line 1.
è號

Но не всегда очевидно, что что-то не так. chr(0xE8) может быть байтом, поэтому:

$ perl -we'print "\xE8\n"'
�

Процесс преобразования значения в серию байтов называется «сериализацией». Конкретный случай сериализации текста известен как кодировка символов.

Encode encode используется для обеспечения кодировки символов. Вы также можете автоматически вызывать encode с помощью модуля open.

$ perl -we'use open ":std", ":locale"; print "\xE8\x{865F}\n"'
è號

$ perl -we'use open ":std", ":locale"; print "\xE8\n"'
è
...