一个乱码引发的学案

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支持多种多字节编码,需要在配置中指明是那种编码。

extension=php_mbstring.dll
mbstring.internal_encoding = UTF-8
original function overloaded function
mail() mb_send_mail()
strlen() mb_strlen()
strpos() mb_strpos()
strrpos() mb_strrpos()
substr() mb_substr()
strtolower() mb_strtolower()
strtoupper() mb_strtoupper()
stripos() mb_stripos()
strripos() mb_strripos()
strstr() mb_strstr()
stristr() mb_stristr()
strrchr() mb_strrchr()
substr_count() mb_substr_count()
ereg() mb_ereg()
eregi() mb_eregi()
ereg_replace() mb_ereg_replace()
eregi_replace() mb_eregi_replace()
split() mb_split()
$s="abc中文替换,";
 echo bin2hex($s) . "\n";
 echo "string length: " . strlen($s) . "\t" . mb_strlen($s,'UTF-8') . "\n";

但是考虑到有些服务器可以没有配置这个模块,还有哪些方法呢?

强大的正则表达式

Function replacements
POSIX PCRE
ereg_replace() preg_replace()
ereg() preg_match()
eregi_replace() preg_replace()
eregi() preg_match()
split() preg_split()
spliti() preg_split()
sql_regcase() No equivalent

POSIX将要废弃,在PCRE模式中,/u,可以指明让表达式支持UTF-8

/u (PCRE_UTF8)
This modifier turns on additional functionality of PCRE that is incompatible with Perl. Pattern strings are treated as UTF-8.


//字符串的长度
echo preg_match_all("/.{1}/us",$s,$dummy) . "\n";

//trim
$s=”匹 配全,角,空格、,,;.。:  “;

//$s = mb_ereg_replace(‘^(([ \r\n\t])*( )*)*’, ”, $s);
echo $s . “\n”;
echo preg_replace(“/[ \s\,,;;\::、。\. ]+$/u”,”,$s) . “\n”;

//匹配中文
if(preg_match_all(“/[\x{4e00}-\x{9fa5}]+/u”,$s,$matches)){
var_dump($matches);
}
$chars = preg_split(‘//u’, $s, -1, PREG_SPLIT_NO_EMPTY);
print_r($chars);

新书推荐

 » 转载文章请注明,转载自:博耘生物 » 《一个乱码引发的学案》
 » 原文链接:http://boyun.sh.cn/bio/?p=2004

发表评论

电子邮件地址不会被公开。 必填项已用*标注

请启用Javascript,以完成验证!