加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl中utf-8编码的处理

发布时间:2020-12-16 00:10:12 所属栏目:大数据 来源:网络整理
导读:为了比较方便,考虑这样一个应用:把html页面中的所有非汉字字符全部去掉。 这里顺便告诉大家一个秘诀,只要文本被perl 按正确编码解释后,利用/w就可以匹配一个字母、数字、_、汉字,这个特性是不是很方便,所以我们只要用如下两次正则表达式就可以去掉所有

为了比较方便,考虑这样一个应用:把html页面中的所有非汉字字符全部去掉。

这里顺便告诉大家一个秘诀,只要文本被perl 按正确编码解释后,利用/w就可以匹配一个字母、数字、_、汉字,这个特性是不是很方便,所以我们只要用如下两次正则表达式就可以去掉所有非汉字字符,包括全角的一些标点(@#$%<,())也能去的很干净:
$str =~ s/[^w]//g;
$str =~ s/[0-9a-zA-Z_]//g;
问题在于如何让perl正确的理解我们的文本,我先给出我们的测试程序如下:
#! /usr/bin/perl?

use strict;
use Encode;
use open IN => ":raw",OUT => ":raw";


my $arg = $ARGV[0];
sub aaa {
        open FH,"testutf8" or die "aaa$! ";
        local $/ = undef;
        binmode FH,":utf8";
        my $str = <FH>;
        return $str;
}
sub bbb {
        open FH,"testutf8";
        local $/ = undef;
        binmode FH,":raw";
        my $str = <FH>;
        $str = pack "U0C*",unpack "C*",$str;
        return $str;
}
sub ccc {
        open FH,":raw";
        my $str = <FH>;
        $str = Encode::decode_utf8($str);
        return $str;          
}
sub ddd {
        open FH,"testutf8" or die "aaa$! ";
        local $/ = undef;     
        binmode FH,":raw";   
        my $str = <FH>;       
        $str = decode('utf-8',$str);  
        return $str;
}
sub eee {
        open FH,"testgb" or die "aaa$! ";
        local $/ = undef;
        binmode FH,":raw";
        my $str = <FH>;
        Encode::from_to($str,'gbk','utf-8');
        $str = Encode::decode_utf8($str);
        return $str;
}
sub fff {
        my $str = `iconv -f gbk -t utf-8 testgb`;
        $str = Encode::decode_utf8($str);
        return $str;
}
my $f;
eval("$f = *$arg");
for (my $i = 0; $i < 200; $i++) {
        my $str = &$f();
        #print "$i ",(length $str)." ";
}
my $str;
$str = &$f();
$str =~ s/[^w]//g;
$str =~ s/[0-9a-zA-Z_]//g;
print $str;
这里共有aaa-fff六个方法,其中aaa-ddd四个方法是把一个叫testutf8的文本文件读入并转码,而eee-fff两个方法是读入testgb文本的。 程序运行的时候,第一个参数传入方法名,像这样./test.pl aaa就可以了,在命令前面加time可以统计所花的时间。这里为了避免perl做的干扰,程序一开始用use open IN => ":raw",? OUT => ":raw"; 强制默认的输入输出都不做解释。 这六种方法都是经过测试能正确得到要求的结果的,但是运行速度在我的perl 5.8.0下却是不一样的,如下 aaa ? ?0m0.376s bbb ? ?0m5.263s ccc ? ?0m0.432s ddd ? ?0m2.668s eee ? ?0m0.784s fff ? ?0m1.358s 从结果我们可以看出,方法bbb最慢,它使用了某些文章上推崇的pack、unpack技巧,不仅从语法上来说极其恶心,效率也是最差 而方法ddd和ccc同样使用了Encode模块,做了同样的事,效率却差的很大,可见Encode模块还是存在缺陷的。也就是说decode方法比decode_utf8方法慢的太多了。 方法aaa并没有太出色的表现,不过也居第一,说明perl底层对utf-8的直接支持还算行。 作为一个反映perl底层糟糕的例子,把":utf8"改成":encoding(utf-8)"测试一下,用了0m1.650s,慢了400% 作为更多的尝试,考虑一下GBK编码的例子,eee使用了一个迂回战术,先用from_to转成utf-8,然后直接调用decode_utf8以避开decode的调用,fff类似,只不过调用了iconv进程来转。 从这我们看出,linux的进程生成代价果然极低,fff方法的差距竟然比bbb的更小(意思是,perl中的不当编程,导致竟然比反复调用外部程序做的还慢)。 那么decode是否真的很慢呢,把eee方法改动一下,直接调用encode,像这样 $str = Encode::decode('gbk',$str); 我们发现,时间是0m0.727s,也就是说,还是比迂回的方法快。 这种奇怪的现象怎么解释呢, 我懒得去研读Encode模块的实现了,只先这么推测吧: gbk的解码比utf-8要容易得多,所以参数为gbk时的decode方法很快,而参数为utf-8就很慢了。 为什么直接用decode_utf8就这么快呢(比encode用gbk参数还快),只能说,perl对它内置的东西还是做了相当的优化,效率并不低。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读