perl让人纠结的几个问题
2015-12-28 20:34
211 查看
编码格式问题:
编码格式:(Perl Unicode全攻略)http://blog.csdn.net/zhangxinrun/article/details/6409846
编码格式转换:http://blog.csdn.net/sptoor/article/details/5201588
gb2312 gbk unicode utf-8等编码解析:http://www.blogjava.net/NeonWay/archive/2007/01/29/96437.html
这里主要用到了Encode模块的decode、encode函数。要了解这两个函数的作用我们需要清楚几个概念:
1、Perl字符串是使用utf8编码的,它由Unicode字符组成而不是单个字节,每个utf8编码的Unicode字符占1~4个字节(变长)。
2、进入或离开Perl处理环境(比如输出到屏幕、读入和保存文件等等)时不是直接使用Perl字符串,而需要把Perl字符串转换成字节流,转换过程中使用何种编码方式完全取决于你(或者由Perl代劳)。一旦Perl字符串向字节流的编码完成,字符的概念就不存在了,变成了纯粹的字节组合,如何解释这些组合则是你自己的工作。
encode函数顾名思义是用来编码Perl字符串的。它将Perl字符串中的字符用指定的编码格式编码,最终转化为字节流的形式,因此和Perl处理环境之外的事物打交道经常需要它。其格式很简单:
$octets = encode(ENCODING, $string [, CHECK])
$string: Perl字符串
encoding: 是给定的编码方式
$octets: 是编码之后的字节流
check: 表示转换时如何处理畸变字符(也就是Perl认不出来的字符)。一般不需使用
编码方式视语言环境的不同有很大变化,默认可以识别utf8、ascii、ascii-ctrl、iso-8859-1等。
说明:
1)除上面几种默认的,perl中编码方式还可以取:gbk、gbk2312、utf8、utf16、utf16le、ucs-2等。
2)利用decode与encode可以实现不同编码方式的转换,但不是直接转换,中间可能会做一些简单的处理。如gbk->uft16le,
对换行符号要转换0A00->0D000A00,中间可能会用到unpack/pack及其对文件进行二进制读写的操作。
3)perl正则表达式,应该utf8格式下进行。对gbk虽然一般情况下可以正常匹配,但特殊时会遇到“代码页”的问题:即第n个汉字的第二个字节和第n+1汉字的第一字节加入正好匹配另一个中文,被替换,则会造成乱码。utf8无此问题。
4)输出到某种编码格式(如“gbk”)的文件: print PF_OUT encode("gbk",decode("uft16",$data)); #从utf16文件到gbk文件,且无论是否binmode输出文件PF_OUT 。
decode函数则是用来解码字节流的。它按照你给出的编码格式解释给定的字节流,将其转化为使用utf8编码的Perl字符串,一般来说从终端或者文件取得的文本数据都应该用decode转换为Perl字符串的形式。它的格式为:
$string = decode(ENCODING, $octets [, CHECK])
$string、ENCODING、$octets和CHECK的含义同上。
UNICODE <-> ASCII:
http://soft.zdnet.com.cn/software_zone/2002/0226/44356.shtml
sub MakeUNICODE {
my ($d) = @_;
$d =~ s/(.)/$1\x00/g;
return $d;
}
sub MakeASCII {
my ($d) = @_;
$d =~ s/(.)x00/$1/g;
return $d;
}
注意:只有前面的255个UNICODE字符可以映射ASCII字符表,所以许多UNICODE字符是不能转换的。
utf8->unicode:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=1714677&page=1#pid12263755
sub Utf8ToUnicode()
{
my($uft8Str)=@_;
my $unicodeStr;
#my $bom_big_endian = pack("n", 0xfeff);
#my $unicode_str_big_endian = encode("UCS-2", $uft8Str);
#$unicodeStr = $bom_big_endian.$unicode_str_big_endian;
my $bom_little_endian = pack("n", 0xfffe);
my $unicode_str_little_endian = pack("n*", unpack("v*", encode("UCS-2", $uft8Str)));
$unicodeStr = $bom_little_endian.$unicode_str_little_endian;
return $unicodeStr;
}
perl子程序传递、返回多个数组问题:
http://zhidao.baidu.com/question/343423708.html
#输入传递多数组,且返回多数组实例(以数组引用实现):
sub choose()
{
my ($pArr1, $pArr2, $pArr3)=@_;
....... #子程序内,使用@$pArr1作为数组;
my (@a1,@a2,@a3);
return (\@a1,\@a2,\@a3); #返回数组的引用
}
my (@a1,@a2,@a3);
my (@r1,@r2,@r3);
my @refs= &choose(\@a1,\@a2,\@a3); #调用时,传递数组的引用;以一个数组来接收返回值(元素为数组的引用)。
@r1 = @{$refs[0]};
@r2 = @{$refs[1]};
@r3 = @{$refs[2]};
说明:
1.首先perl中只能对简单的列表赋值给变量列表,而不能将列表赋值给,列表组成的列表。
比如@arr = (1,2,3);这个是可以的,($a,$b) = ($b, $a);这个也对, 但是(@arr1, @arr2) = (@arr2, @arr1); 这个就错了,原因在于perl的列表是贪婪的, 也就是说 @arr1会尽可能的接受后面的数据,而(@arr2,@arr1)本身就是一个大的列表, 就全部被@arr1接受了,而@arr2为空。这个结论,同样适用于哈希数组(关联数组)。
但是,如果只有一个数组,并且将数组置于列表的最后一个元素,如($a,@arr)=($b,@arrb);是可以得到预期结果的。利用这一点,当只需要传递一个数组时,也可以my($param1,...,@arr)=@_;的形式来传递数组。当然,传递数组引用的方法是普遍适用的。
2.唯一的办法就是以数组引用形式来传递数据。所以($ref_a1, $ref_a2) = (\@a1, \@a2);这种形式是可以的。
使用时可以还原引用,如 @{$ref_a1},或者直接读下标,$ref_a1->
.
编码格式:(Perl Unicode全攻略)http://blog.csdn.net/zhangxinrun/article/details/6409846
编码格式转换:http://blog.csdn.net/sptoor/article/details/5201588
gb2312 gbk unicode utf-8等编码解析:http://www.blogjava.net/NeonWay/archive/2007/01/29/96437.html
这里主要用到了Encode模块的decode、encode函数。要了解这两个函数的作用我们需要清楚几个概念:
1、Perl字符串是使用utf8编码的,它由Unicode字符组成而不是单个字节,每个utf8编码的Unicode字符占1~4个字节(变长)。
2、进入或离开Perl处理环境(比如输出到屏幕、读入和保存文件等等)时不是直接使用Perl字符串,而需要把Perl字符串转换成字节流,转换过程中使用何种编码方式完全取决于你(或者由Perl代劳)。一旦Perl字符串向字节流的编码完成,字符的概念就不存在了,变成了纯粹的字节组合,如何解释这些组合则是你自己的工作。
encode函数顾名思义是用来编码Perl字符串的。它将Perl字符串中的字符用指定的编码格式编码,最终转化为字节流的形式,因此和Perl处理环境之外的事物打交道经常需要它。其格式很简单:
$octets = encode(ENCODING, $string [, CHECK])
$string: Perl字符串
encoding: 是给定的编码方式
$octets: 是编码之后的字节流
check: 表示转换时如何处理畸变字符(也就是Perl认不出来的字符)。一般不需使用
编码方式视语言环境的不同有很大变化,默认可以识别utf8、ascii、ascii-ctrl、iso-8859-1等。
说明:
1)除上面几种默认的,perl中编码方式还可以取:gbk、gbk2312、utf8、utf16、utf16le、ucs-2等。
2)利用decode与encode可以实现不同编码方式的转换,但不是直接转换,中间可能会做一些简单的处理。如gbk->uft16le,
对换行符号要转换0A00->0D000A00,中间可能会用到unpack/pack及其对文件进行二进制读写的操作。
3)perl正则表达式,应该utf8格式下进行。对gbk虽然一般情况下可以正常匹配,但特殊时会遇到“代码页”的问题:即第n个汉字的第二个字节和第n+1汉字的第一字节加入正好匹配另一个中文,被替换,则会造成乱码。utf8无此问题。
4)输出到某种编码格式(如“gbk”)的文件: print PF_OUT encode("gbk",decode("uft16",$data)); #从utf16文件到gbk文件,且无论是否binmode输出文件PF_OUT 。
decode函数则是用来解码字节流的。它按照你给出的编码格式解释给定的字节流,将其转化为使用utf8编码的Perl字符串,一般来说从终端或者文件取得的文本数据都应该用decode转换为Perl字符串的形式。它的格式为:
$string = decode(ENCODING, $octets [, CHECK])
$string、ENCODING、$octets和CHECK的含义同上。
UNICODE <-> ASCII:
http://soft.zdnet.com.cn/software_zone/2002/0226/44356.shtml
sub MakeUNICODE {
my ($d) = @_;
$d =~ s/(.)/$1\x00/g;
return $d;
}
sub MakeASCII {
my ($d) = @_;
$d =~ s/(.)x00/$1/g;
return $d;
}
注意:只有前面的255个UNICODE字符可以映射ASCII字符表,所以许多UNICODE字符是不能转换的。
utf8->unicode:http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=1714677&page=1#pid12263755
sub Utf8ToUnicode()
{
my($uft8Str)=@_;
my $unicodeStr;
#my $bom_big_endian = pack("n", 0xfeff);
#my $unicode_str_big_endian = encode("UCS-2", $uft8Str);
#$unicodeStr = $bom_big_endian.$unicode_str_big_endian;
my $bom_little_endian = pack("n", 0xfffe);
my $unicode_str_little_endian = pack("n*", unpack("v*", encode("UCS-2", $uft8Str)));
$unicodeStr = $bom_little_endian.$unicode_str_little_endian;
return $unicodeStr;
}
perl子程序传递、返回多个数组问题:
http://zhidao.baidu.com/question/343423708.html
#输入传递多数组,且返回多数组实例(以数组引用实现):
sub choose()
{
my ($pArr1, $pArr2, $pArr3)=@_;
....... #子程序内,使用@$pArr1作为数组;
my (@a1,@a2,@a3);
return (\@a1,\@a2,\@a3); #返回数组的引用
}
my (@a1,@a2,@a3);
my (@r1,@r2,@r3);
my @refs= &choose(\@a1,\@a2,\@a3); #调用时,传递数组的引用;以一个数组来接收返回值(元素为数组的引用)。
@r1 = @{$refs[0]};
@r2 = @{$refs[1]};
@r3 = @{$refs[2]};
说明:
1.首先perl中只能对简单的列表赋值给变量列表,而不能将列表赋值给,列表组成的列表。
比如@arr = (1,2,3);这个是可以的,($a,$b) = ($b, $a);这个也对, 但是(@arr1, @arr2) = (@arr2, @arr1); 这个就错了,原因在于perl的列表是贪婪的, 也就是说 @arr1会尽可能的接受后面的数据,而(@arr2,@arr1)本身就是一个大的列表, 就全部被@arr1接受了,而@arr2为空。这个结论,同样适用于哈希数组(关联数组)。
但是,如果只有一个数组,并且将数组置于列表的最后一个元素,如($a,@arr)=($b,@arrb);是可以得到预期结果的。利用这一点,当只需要传递一个数组时,也可以my($param1,...,@arr)=@_;的形式来传递数组。当然,传递数组引用的方法是普遍适用的。
2.唯一的办法就是以数组引用形式来传递数据。所以($ref_a1, $ref_a2) = (\@a1, \@a2);这种形式是可以的。
使用时可以还原引用,如 @{$ref_a1},或者直接读下标,$ref_a1->
.
相关文章推荐
- Shell 脚本编程陷阱
- VBS脚本写的Windows硬件检测工具分享
- Perl模块编写说明
- perl如何避免脚本在windows中闪一下就关闭
- Perl中的特殊内置变量详细介绍
- 用vbscript实现隐藏任务栏图标的脚本
- 用autoit编写第一个脚本(Hello World)
- VBS调用WMI快速关闭IE的脚本
- Oracle数据库执行脚本常用命令小结
- 收集的ROS防火墙脚本
- JSP脚本漏洞面面观
- 不错的批处理脚本 第一部分
- VBS脚本加密/解密VBS脚本(简易免杀版1.1)
- 不错的批处理脚本实例代码 第二部分
- linux下使用perl获取本机ip的几种方法介绍
- 使用脚本和批处理清除电脑中的痕迹的代码第1/2页
- 让你的脚本说话
- Lua脚本获取喜马拉雅MP3音频地址
- perl 控制结构 条件控制 if while