昨天在测试一个网页接口,页面返回GBK类型的xml数据,对其进行xml的解析,而后打印遇到了编码问题,随后查了相关资料,顺利解决,总结一下。html
Perl中的字符串有两种形式,一种是字节数组,另外一种是utf-8编码的字符串。数组
Perl如何肯定当前字符串是属于哪种呢?在Perl的内部,一个字符串是由两部分组成的,除了包含字符串主体数据外还有一个属性utf8 flag,这是字符串的一个状态属性,根据这个状态,Perl就会知道将字符串当成哪一种形式来处理。测试
utf8 flag为Off时,Perl会将字符串看成字节数组来处理。ui
utf8 flag为On时,Perl会将字符串看成utf8编码字符串来处理。编码
判断一个字符串的utf8 flag的状态能够经过Encode::is_utf8($str)方法。spa
一个字符串的不一样utf8 flag状态时,对某些操做都是会受影响的,例如:.net
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-8unix
执行结果:code
2xml
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