Perl编码
昨天在测试一个网页接口,页面返回GBK类型的xml数据,对其进行xml的解析,然后打印遇到了编码问题,随后查了相关资料,顺利解决,总结一下。
Perl中的字符串有两种形式,一种是字节数组,另一种是utf-8编码的字符串。
Perl如何确定当前字符串是属于哪一种呢?在Perl的内部,一个字符串是由两部分组成的,除了包含字符串主体数据外还有一个属性utf8 flag,这是字符串的一个状态属性,根据这个状态,Perl就会知道将字符串当成哪种形式来处理。
utf8 flag为Off时,Perl会将字符串当作字节数组来处理。
utf8 flag为On时,Perl会将字符串当作utf8编码字符串来处理。
判断一个字符串的utf8 flag的状态可以通过Encode::is_utf8($str)方法。
一个字符串的不同utf8 flag状态时,对某些操作都是会受影响的,例如:
1 use Encode; 2 3 my $str = '你好'; 4 Encode::_utf8_on($str); 5 my $len = length($str); 6 print $len."\n"; 7 Encode::_utf8_off($str); 8 my $len = length($str); 9 print $len."\n";
备注:脚本文件编码为utf-8
执行结果:
2
6
Perl字符串的编码状态对正则的操作也是有影响的,如下:
1 use Encode; 2 3 my $str1= 'hello-----科大讯飞'; 4 my $str2= 'hello-----科大讯飞'; 5 6 Encode::_utf8_on($str1); 7 Encode::_utf8_off($str2); 8 9 $str1=~s/\W+//g; 10 $str2=~s/\W+//g; 11 12 $str1 = encode("gbk",$str1); 13 print $str1."\n"; 14 print $str2."\n";
第12行代码是为了在命令提示符下显示中文,因为该脚本文件本身为utf-8编码。
程序执行结果:
hello科大讯飞
hello
根据以上结果我们可以看出,不同的Perl字符串形式对正则是有影响的。
接下来简单介绍下Perl中编码的转换。
若你有一字符串“你好”,编码为gb2312,utf8 flag为off,我们知道,该字符串会被当作字节数组,若这时,你强行改变utf8 flag为on的话,那么该字符串就会被当作utf-8字符串来处理,该字符串本身就是gb2312的,你非要让其当作utf-8,肯定会出现错误【乱码异常等】,对于一个gb2312编码的字符串如何将其转成utf-8呢?
代码如下:
$str = Encode::decode("gb2312", $str); $str = Encode::encode("utf8",$str);
在执行上句之前,$str的utf8 flag一定要是off的,否则会影响decode解码。
上句代码的意思是将$str字符串,根据gb2312编码,转换成Perl的内部格式,然后再从Perl的内部格式通过encode方法编码成utf8的编码。
执行完encode语句之后,utf8 flag的状态会被设置成on状态。
关于Perl编码方面还有很多的内容,可参考:http://blog.chinaunix.net/uid-23622436-id-2394070.html