NND,看了一周Perl的编码问题了,还是迷迷糊糊的 !
读书百遍 其义自见
GO ON !
编码问题确实是一个恼火的问题,啊啊啊啊啊!
Perl中的编码
在Perl看来,字符串只有两种形式.一种是octets,即8位序列,也就是我们通常说的字节数组.另一种utf8编码的字符串,perl管它叫string.也就是说:Perl只认识两种编码: Ascii(octets)和utf8(string).
perl对两种形式的识别通过 utf8 flag 来标识.当 utf8 flag为on时,Perl把字符串当成utf8编码,当为off时,Perl把字符串当成Ascii编码.
Perl默认输入和输出的都是octets字节流,都是没有语义的.
所有的字符函数包括正则表达式都要受到utf flag的影响.
比如length()函数,返回字符的长度.以utf8字符'中'(0xe40xb8oxad)为例,当utf8 flag为off,将返回3.当utf8 flag为on,将返回1.
开启utf8 flag : Encode::decode Encode::_utf8_on
关闭utt8 flag : Encode::encode Encode::_utf8_off
判断utf8 flag : Encode::is_utf8
Perl编码转换
use Encode;
$string = decode( 'coding',$octets );
把外部接收的coding编码的字符数组转换为内部utf8编码的字符串,并置utf8 flag为on.(两个作用)
$octets = encode( 'coding',$string );
把内部utf8编码的字符串转换为coding编码的字符数组,并置utf8 flag为off. (两个作用)
以上两个函数都具有两个作用:一为转码,二为修改utf8 flag.
ACSII编码的utf8 flag一直为off.
本来就为utf8编码的外部字符数组并不与内部的utf8相同,此时utf8 llag并没有打开,Perl并不能识别他为utf8,所以一样需要打开utf8 flag标识,使Perl识别为utf8编码.
当utf8 flag为on而输出字符串,将报警告为 "Wide character in print at txt.pl line 10, line 1."
默认值(1)命令行参数和标准输入
输入的字符串与locale相关,utf8 flag为off.
(2)源代码字符串
与保存文件的编码相同,utf8 flag为off.
如果使用了use utf8,且保存文件为utf8格式,此时utf8 flag为on.
如果字符串使用了\x{....}格式,表示为unicode编码,并自动转换内部的utf8格式,并置utf8 flag为on.
(3)文件读取
与文件的编码格式相同,utf8 flag为off.
PerlIO
PerlIO为我们的输入/输出转码提供了便利.它可以针对某个文件句柄,输入的时候自动帮你转码并开启utf8 flag,输出的时候,自动帮你转码并关闭utf8 flag.
binmode(STDIN, ":encoding('coding')");
open(F,"<:encoding('coding')","filepath");
表示把输入的'coding'编码的字符数组转换为内部utf8编码的字符串,并置utf8 flag为on.
binmode(STDOUT,":encoding('coding')");
open(F,">:encoding('coding')","filepath");
表示把内部的utf8编码的字符串转换为'coding'编码的字符数组作为输出,并置utf8 flag为off.
pack/unpack虽然和编码没什么关系,但在编码的另一种转换时经常用到.
http://blog.chinaunix.net/u3/91603/showart_2087980.html还是很多不清楚 继续看文档吧
详见 perldoc Encode,perldoc PerlIO,perldoc perlpacktut,perldoc perlunicode,perldoc perluniintro
阅读(1601) | 评论(1) | 转发(0) |