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

技术改变未来
原文地址:https://www.cnblogs.com/CodeTracker/p/4721100.html