设为首页 收藏本站
查看: 1409|回复: 0

[经验分享] [转载] 关于Perl的编码,字节流了字符

[复制链接]

尚未签到

发表于 2015-12-27 13:35:35 | 显示全部楼层 |阅读模式
  在perl的maillist看到一封大牛(cnhacktnt)解释编码的mail,, perl字节流和字符流, 说的非常清晰, 也加深了自己对perl字符编码的理解. share一下.
  需要分清楚“字符(character)”和“字节流(Octet stream)”的概念,你的perl程序所取到的输入,以及它对外的输出(就像你用print打印)都是字节流,字节流是没有语义的,对perl来说它就是一堆字节,没有额外的意义。
而字符串和字节流是不同的,字符串有语义,它代表某个或某些个字符,直白来说,我们看到的“abcd1234“等等都是字符。而字节流可以用来表示字符串,同一个字符串,它对应的字节流可以不同,为什么呢?因为同一个字符串可以用不同的编码方式(如utf8或gb2312)来编码,编码过后得到的,便是相对应的字节流。
在perl中,你输入的一个字符串是以字节流的形式传递给perl的,如果你想perl把你输入的字符串真正当成字符串来理解和操作,你需要告诉perl这串字符的编码是什么,比如(我的环境为utf8):
  use Encode;
$string=”中国”;
$string_decoded=decode_utf8($string);
  此时,$string 对perl来说只是用utf8编码过的字节流(十六进制为\xE4\xB8\xAD\xE5\x9B\xBD),这个时候,perl只会按字节来对他操作,因为perl不知道它是啥东西。
而 $string_decoded 对perl来说就是有语义的字符串了,虽然他本身在perl内部是以UTF8编码的方式存储的,但是它已经被打上了标记,perl知道它是字符串,该按字符来操作,此时如果你用substr之类的函数对 $string_decoded 操作的话,便是按 “中(\xE4\xB8\xAD)”,“国(\xE5\x9B\xBD)” 两个字符来操作了,而不是在未 decode 之前,以一个字节一个字节的方式处理。
  在输出的时候,我们应该仍以字节流的方式输出,因为字符只是一个概念,一个具象,它可以有不同的表现形式(不同编码的字节流),这个时候你可以根据下一个需要取得你这个输出作为输入的目标程序的要求(网络要求,编码要求),来对你的输出进行编码(成字节流),然后再传输给它。所以这个时候,你需要对需要输出的字符串进行 encode,比如:
  use Encode;
$string=”中国”;
$string_decoded=decode_utf8($string);
$string_encoded=encode(“gb2312″, $string_decoded);
print $string_encoded;
  这个时候, $string_encoded 中便是以 gb2312 编码方式编码过的字节流了(它同样代表“中国”这个字符串)。
如果你直接输出 $string_decoded 而不做 encode 的话,perl 便会按这个字符串在其内存中保存的方式(也就是utf8)输出,如果你是 utf8 的环境,你可以看到正确的字符串,但如果你这个字符串里面一旦包含了大于\xFF的字节,那么perl会警告”Wide character in print…”。那为什么我 encode 了这个字符串后perl不会报这个警告呢?那是因为perl会对“字符串”做标记,decode会打上标记,encode后会去掉这个标记,一旦你输出的时候有这个标记,并且有字节大于\xFF,perl就会丢出那个警告,下次你看到这个警告,一眼就可以看出是因为你程序的某个输出没有经过编码转换成字节流的缘故的。
  呃。。。我是不是有点太罗嗦了。。。
Anyway, 希望大家对 Perl 的 encoding 有个了解。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-156978-1-1.html 上篇帖子: perl学习:perl调试命令 下篇帖子: 小时代5-perl 常量、多维数组及变量的初始化
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表