William Jiang

JavaScript,PHP,Node,Perl,LAMP Web Developer – http://williamjxj.com; https://github.com/williamjxj?tab=repositories

Perl Octets, utf8 and encode

Perl has 2 types of strings: Ascii (octets), utf8 (string). Here I summary Perl’s garbled issues and solutions between utf8, gbk, gb2312. Some good references include: http://blog.chinaunix.net/uid-20639775-id-3382620.html.

字符串读入乱码

读入的内容乱码有两种情形:
1. 字符串本来不是utf8编码的, 应该先把它转成utf8编码, 并且使它的utf8 flag处于开启状态. 比如下面将gbk转换成utf8编码。

my $out=decode("gbk",$str);
my $url='http://www.baidu.com';
my $content=get $url;
die "Couldn't get $url" unless defined $content;
my $out=decode("gbk",$content);
print $out,"\n";

字符串编码本来就是utf8, 只是utf8 flag没有打开, 那么你可以使用以下方式中的任一种来开启utf8 flag

$str = Encode::decode_utf8($str);
$str = Encode::decode("utf8", $str);
Encode::_utf8_on($str);

字符串输出乱码

字符串在程序内被正确地处理后, 要展现给用户. 这时我们需要把字符串从perl internal form转化成用户能接受的形式. 简单地说, 就是把字符串从utf8编码转换成输出的编码或表现界面的编码. 这时候, 我们使用如下代码来将utf8的编码转换成其他的编码:

//charset:utf8,euc-cn,gb2312,gbk...
$str = Encode::encode('charset', $str);

Perl Encode (encode/decode)

1、Perl字符串是使用utf8编码的,它由Unicode字符组成而不是单个字节,每个utf8编码的Unicode字符占1~4个字节(变长)。
2、 进入或离开Perl处理环境(比如输出到屏幕、读入和保存文件等等)时不是直接使用Perl字符串,而需要把Perl字符串转换成字节流,转换过程中使用 何种编码方式完全取决于你(或者由Perl代劳)。一旦Perl字符串向字节流的编码完成,字符的概念就不存在了,变成了纯粹的字节组合,如何解释这些组 合则是你自己的工作。

我们可以看出如果想要Perl按照我们的字符概念来对待文本,文本数据就需要一直用Perl字符串的形式存放。但是我们平时写出的每个字符一般都被 作为纯 ASCII字符保存(包括在程序中明文写出的字符串),也就是字节流的形式,这里就需要encode和decode函数的帮助了。

encode函数顾名思义是用来编码Perl字符串的。它将Perl字符串中的字符用指定的编码格式编码,最终转化为字节流的形式,因此和Perl处理环境之外的事物打交道经常需要它。其格式很简单:

$octets = encode(ENCODING, $string [, CHECK])

这里$string是Perl字符串,ENCODING是给定的编码方式,$octets则是编码之后的字节流,CHECK表示转换时如何处理畸变字符(也就是Perl认不出来的字符)。一般不需要使用CHECK,让Perl按默认规则处理即可。
编 码方式视语言环境的不同有很大变化,默认可以识别utf8、ascii、ascii-ctrl、iso-8859-1等,中文环境(CN)增加了euc-cn(gb2312与之等价)、cp936(gbk与之等价)、hz等,还有日文环境(JP)、韩文(KR)等等,在此不一一尽数。encode之后,Perl的utf8 flag是off。

decode函数则是用来解码字节流的。它按照你给出的编码格式解释给定的字节流,将其转化为使用utf8编码的Perl字符串,一般来说从终端或者文件取得的文本数据都应该用decode转换为Perl字符串的形式。它的格式为:

$string = decode(ENCODING, $octets [, CHECK])

decode之后,Perl的utf8 flag 是on 状态。

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: