一个乱码引发的学案

php开发的系统中,在对用户填写的tag做切分时,一个单词【表格】出现了乱码,其他都正常。借着这段时间对于字符的深究,抽时间研究了这个问题,最后却牵扯到很多东西——PHP对于Unicode支持,及其相关字符处理的问题。

出现乱码,肯定是字符处理过程中出现了问题,跟踪后,发现问题出在trim这个步骤。

$tags_str=trim($tags_str,",,;; \n\t\r");

本意是去除标签字符串后面的标点符号及其换行、空白,但是遇到“表格”就出现问题了。用到的字符编码是UTF-8

E8A1A8 E6A0BC
, 2C ,全角 EFBC8C
; 3b ;全角 EFBC9B

又到PHP文档上查了下对于函数的介绍,算是明白了。PHP许多核心字符函数,都只是针对ASCII,单字节编码的字符(0x00~0x7f),如果使用这些函数去操作多字节字符,就会遇到问题,比如trim,按照单字节去操作,就会将0xBC裁掉,“表格”编码不全,自然也就乱码。同样strlen得到的长度也是字节的长度,对于UTF-8来说,就不是字符数。

如何来解决这个问题?

PHP有专门的处理多字节(Multibyte String)的模块-mbstring,但是该模块不是默认安装的,编译时增加–enable-mbstring,或者更改配置启用该模块,mbstring支持多种多字节编码,需要在配置中指明是那种编码。 Continue reading

存文本文件及其字符编码

网上也有许多关于纯文本的讨论,如果在搜索“乱码”,更是不尽其数。如果你开始命令行,开始编码,开始数据分析,开始操作中文,存文本及其字符编码便是最基础的东西。而往往基础的东西,真正弄懂更为不易,而或者你已经有了多年相关的经验,也不一定搞清楚了。

什么是存文本文件?

存文本由可打印字符组成,人可以直接阅读和理解其形式。

纯文本并非意味着文本是无结构的,HTML、SGML、XML等都是有良好结构定义的存文本,与直接的二进制编码相比,纯文本所处的层面往往更高。大多数二进制格式的问题在于,理解数据所必须的语境与数据本身是分离的,没有应用逻辑对其进行解释,这些数据绝对没有意义,但是通过存文本,可以获得自描述的、不依赖创建它的应用的数据流。对于大多数二进制文件,要成功的进行解析,你必须了解整个格式的所有细节。

缺点:

  • 与压缩的二进制格式相比,存储纯文本所需空间更多
  • 要解释与处理纯文本文件,计算上的代价可能更昂贵

优点: