perl中字符串编码分析和注意事项
2017-12-23 11:41
357 查看
》在 Perl看来, 字符串只有两种形式. 一种是octets, 即8位序列, 也就是我们通常说的字节数组. 另一种utf8编码的字符串, perl管它叫string. 也就是说: Perl只熟悉两种编码: Ascii(octets)和utf8(string).
perl内部字符串由flag标志位和数据区两部分组成,其存储结构如下:
假如utf8 flag是On perl就会把数据区内容当成utf8字符串来处理;
假如utf8 flag是Off, perl就会把数据区内容当成octets来处理. 即字节来处理;
所有字符串相关的函数包括正则表达式、文件检测、都会受utf8 flag的影响。在默认情况下,utf8 flag标志位是off状态,当我们在代码中使用了 use utf8 ,则代表flag标志位是on状态,在当前词法范围内都是有效的。
Encode中的is_utf8函数可以用于检测当前flag开启情况,1代表on 0代表off;以下代码均是使用notepad++进行编码,字符编码格式选择UTF-8格式。
$octets = encode(ENCODING, STRING);
将标量字符串STRING从perl内部格式编码成ENCODING格式,并且返回字节流序列。
$string = decode(ENCODING, OCTETS);
以ENCODING编码格式从字节流中解读字符信息,并转化为perl内部格式编码。
下面展示gbk和utf8之间的相互转码,两种编码格式需要经过perl内部编码格式:
若待编码的字符串已经是perl内部编码格式(flag on +utf8编码),则可以直接进行编码或者解码,不需要按照上述的过程进行。
例子1:
运行结果:
例子2:
运行结果:
我在目录下这个路径下创建了txt文件“E:\perl\文件夹1\log.txt”,不同的编码格式答案是不符合预期的。
例子3:
运行结果:
字符串来源
为了能够正确的进行字符串编解码, 我们首先要知道字符串本来的编码和utf8 flag开关情况, 这里我们讨论几种情况.
命令行参数和标准输入. 从命令行参数或标准输入(STDIN)来的字符串, 它的编码跟locale有关. 假如你的locale是zh_CN或zh_CN.gb2312, 那么进来的字符串就是gb2312编码, 假如你的locale是zh_CN.gbk, 那么进来的编码就是gbk, 假如你的编码是zh_CN.UTF8, 那进来的编码就是utf8. 不管是什么编码, 进来的字符串的utf8 flag都是关闭的状态.
你的源代码里的字符串. 这要看你编写源代码时用的是什么编码. 在editplus里, 你可以通过”文件”->”另存为”查看和更改编码. 在linux下, 你可以cat一个源代码文件, 假如中文正常显示, 说明源代码的编码跟locale是一致的. 源代码里的字符串的utf8 flag同样是关闭的状态.
假如你的源代码里含有中文, 那么你最好遵循这个原则: 1) 编写代码时使用utf8编码, 2)在文件的开头加上use utf8;语句. 这样, 你源代码里的字符串就都会是utf8编码的, 并且utf8 flag也已经打开.
从文件读入. 这个毫无疑问, 你的文件是什么编码, 读进来就是什么编码了. 读进来以后, utf8 flag是off状态.
抓取网页. 网页是什么编码就是什么编码, utf8 flag是off状态. 网站的编码可以从响应头里或者html
字符转码API
运行结果:
参考入下资料:
http://blog.csdn.net/c_base_jin/article/details/78768591
perl内部字符串由flag标志位和数据区两部分组成,其存储结构如下:
假如utf8 flag是On perl就会把数据区内容当成utf8字符串来处理;
假如utf8 flag是Off, perl就会把数据区内容当成octets来处理. 即字节来处理;
所有字符串相关的函数包括正则表达式、文件检测、都会受utf8 flag的影响。在默认情况下,utf8 flag标志位是off状态,当我们在代码中使用了 use utf8 ,则代表flag标志位是on状态,在当前词法范围内都是有效的。
Encode中的is_utf8函数可以用于检测当前flag开启情况,1代表on 0代表off;以下代码均是使用notepad++进行编码,字符编码格式选择UTF-8格式。
编码格式转换
若要进行不同编码之间的转换,可以使用Encode模块中的decode函数和encode函数,这两个函数使用如下$octets = encode(ENCODING, STRING);
将标量字符串STRING从perl内部格式编码成ENCODING格式,并且返回字节流序列。
For example, to convert a string from Perl's internal format into ISO-8859-1: $octets = encode("iso-8859-1", $string);
$string = decode(ENCODING, OCTETS);
以ENCODING编码格式从字节流中解读字符信息,并转化为perl内部格式编码。
For example, to convert ISO-8859-1 data into a string in Perl's internal format: $string = decode("iso-8859-1", $octets);
下面展示gbk和utf8之间的相互转码,两种编码格式需要经过perl内部编码格式:
若待编码的字符串已经是perl内部编码格式(flag on +utf8编码),则可以直接进行编码或者解码,不需要按照上述的过程进行。
例子1:
use Encode; #当前关闭 print "utf8 flag is 0ff\n" if !Encode::is_utf8($string1); my $string1 = "你好";//是utf8格式,若不编码屏幕输出乱码 print Encode::encode("gbk",Encode::decode("utf8",$string1)),"\n"; #flag是off状态,当作字节来处理,长度为6 print "length:",length($string1),"\n";
运行结果:
例子2:
print "***********utf8 flag is on***************\n"; #此后utf8 flag 为on use utf8; my $string2 = "你好"; #当前on print "utf8 flag is on\n" if Encode::is_utf8($string2); #这里$string2相当于是内部格式了 flag is on and utf8 format #可以直接编码,不用先解码后编码了 print Encode::encode("gbk",$string2),"\n"; #当作string来处理,长度为2 print "length:",length($string2),"\n\n\n\n";
运行结果:
注意事项
我们在使用perl中的文件测试符-e -s -f或者系统命令copy函数时,均要求这些函数的入参或者变量是gbk编码格式,否则会导致不符合预期的编码结果,举例如下:我在目录下这个路径下创建了txt文件“E:\perl\文件夹1\log.txt”,不同的编码格式答案是不符合预期的。
例子3:
print "**********file test and system copy attentions**************\n"; #文件测试或者调用系统copy函数等函数时 均需要使用gbk编码 my $src1 = "E:\\perl\\文件夹1\\log.txt"; my $src2 = "E:\\perl\\文件夹1\\log.txt"; #$src2字符串flag标志位是on,并且本身是utf8编码, #因此$src2是perl内部格式,可以转为国标 my $gbk_src = Encode::encode("gbk", $src2); print "gbk encode:$gbk_src\n"; #文件存在 则打印 if (-e $gbk_src){ print "it exists\n"; } #文件不存在 则打印 unless (-e $src){ print "it don't exist\n"; }
运行结果:
字符串来源
为了能够正确的进行字符串编解码, 我们首先要知道字符串本来的编码和utf8 flag开关情况, 这里我们讨论几种情况.
命令行参数和标准输入. 从命令行参数或标准输入(STDIN)来的字符串, 它的编码跟locale有关. 假如你的locale是zh_CN或zh_CN.gb2312, 那么进来的字符串就是gb2312编码, 假如你的locale是zh_CN.gbk, 那么进来的编码就是gbk, 假如你的编码是zh_CN.UTF8, 那进来的编码就是utf8. 不管是什么编码, 进来的字符串的utf8 flag都是关闭的状态.
你的源代码里的字符串. 这要看你编写源代码时用的是什么编码. 在editplus里, 你可以通过”文件”->”另存为”查看和更改编码. 在linux下, 你可以cat一个源代码文件, 假如中文正常显示, 说明源代码的编码跟locale是一致的. 源代码里的字符串的utf8 flag同样是关闭的状态.
假如你的源代码里含有中文, 那么你最好遵循这个原则: 1) 编写代码时使用utf8编码, 2)在文件的开头加上use utf8;语句. 这样, 你源代码里的字符串就都会是utf8编码的, 并且utf8 flag也已经打开.
从文件读入. 这个毫无疑问, 你的文件是什么编码, 读进来就是什么编码了. 读进来以后, utf8 flag是off状态.
抓取网页. 网页是什么编码就是什么编码, utf8 flag是off状态. 网站的编码可以从响应头里或者html
字符转码API
#接口API sub convert_utf8_to_gbk{ my ($utf8) = @_; my $gbk = ""; if (Encode::is_utf8($utf8)){ $gbk = Encode::encode('gbk',$utf8); } else{ $gbk = Encode::encode('gbk',Encode::decode('utf8',$utf8)); } return $gbk; } sub convert_gbk_to_utf8{ my ($gbk) = @_; my $utf8 = ""; $utf8 = Encode::decode('gbk',$gbk); return $utf8; } #测试用例 print convert_utf8_to_gbk("你好 中国!!\n"),"\n"; print "input:"; chomp( my $input = <STDIN>); print "output:",convert_utf8_to_gbk(convert_gbk_to_utf8($input)),"\n";
运行结果:
参考入下资料:
http://blog.csdn.net/c_base_jin/article/details/78768591
相关文章推荐
- Redis 数据类型分析 字符串 哈希 列表 集合 有序集合 优缺点 分析 注意事项 存储结构
- Python 字符串编码中中文字符注意事项
- Python【基础:数据类型和变量 字符串和编码 list和tuple 条件判断 循环 dict和set】注意事项(与java,c比较)
- 数据库的存储过程(理解,示例,注意事项,异常分析)
- Android通过http方式获取JSON字符串并解析的注意事项(乱码,小黑框)
- PHP中字符串的使用注意事项
- 软件开发注意事项分析
- 安装oracle10G注意事项以及修改数据库字符集编码
- [转载]PDO防注入原理分析以及使用PDO的注意事项
- 有关BASE64编码的需要注意的事项
- CentOS7安装MariaDB以及编码注意事项
- 黄聪:关于抓取网页,分析网页内容,模拟登陆网站的逻辑/流程和注意事项(转)
- s:if标签字符串比较注意事项
- 执行字符串SQL语句--带有参数的存储过程以及 int类型的字符串变量注意事项
- perl编译安装注意事项
- Mysql安装注意事项、安装失败的五个原因分析
- Python学习笔记-Python的字符串,格式化,条件判断,循环、raw_input的注意事项
- 定义字符串的方式及注意事项
- jsp接收后台全数字的字符串注意事项!
- PDO防注入原理分析以及使用PDO的注意事项总结