如何在perl中正确显示HTML实体

时间:2011-09-12 09:59:19

标签: html perl html-entities

我正在使用PERL编写一个Web爬虫,当我尝试使用HTML :: Entities :: decode_entities显示字符串时,我意识到有一种奇怪的行为。

我正在处理包含中文字符和Jìngyè字符串的字符串。 我使用HTML :: Entities :: decode_entities来解码汉字,效果很好。但是,当字符串不包含中文字符时,字符串显示很奇怪(J ngy )。

我写了一个小代码来测试2个字符串上的不同行为。

字符串1是“台湾台北市中山区J ngy 第三路22号10466”,字符串2是“104台湾台北市中山区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";

这些是我的结果:

之前:台湾台北市中山区J ngy 第二路22号10466

解码台湾台北市中山区Jìngyè第三路22号10466号(正确)

切碎:台湾台北市中山区J ngy 第三路22号10466(不正确)

之前:104台湾台北市中山区J ngy 3路20号

解码104台湾台北市中山区Jìngyè3,3路20号号(正确)

切碎:104台湾台北市中山区Jìngyè3,3路20号(正确)

有人可以解释一下,为什么会发生这种情况?以及如何解决这个问题,以便我的String能够正常显示。

非常感谢。

抱歉,我没有明白我的问题,下面是我写的代码,其中网址为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 个答案:

答案 0 :(得分:2)

首先,始终使用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用于提供字符编码。您也可以使用open模块自动调用encode

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

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