分割gbk中文出现乱码的问题解决

近日遇到一个神奇的字“弢(tao)”。

具体的过程是这样的:

1 $list = explode('|', 'abc弢|bc');
2 var_dump($list);

取得这个分割的结果。

和想象不同,结果居然是这样:

array(3) {
  [0]=>
  string(4) "abc?
  [1]=>
  string(0) ""
  [2]=>
  string(2) "bc"
}

出现了乱码,而且莫名其妙的出现了一个空元素。

究其原因,原来这个字“弢”的gbk编码是8f7c,而|的ASCII是7c,这样explode就把弢的第二ASCII作为|切割了。

既然是双字节的问题,我们用mbstring解决好了。

可惜,php并没有mb_explode这种函数,找了找,找到一个mb_split。

array mb_split ( string $pattern , string $string [, int $limit = -1 ] )

没有声明编码的地方。仔细一看,他是通过mb_regex_encoding声明编码的。

于是写出以下的代码:

1 mb_regex_encoding('gbk');
2 $list = mb_split('\|', 'abc弢|bc');
3 var_dump($list);

结果php报错,mb_regex_encoding不认识gbk,囧。

那就使用它认识的:

1 mb_regex_encoding('gb2312');
2 $list = mb_split('\|', 'abc弢|bc');
3 var_dump($list);

结果:

array(3) {
  [0]=>
  string(4) "abc?
  [1]=>
  string(0) ""
  [2]=>
  string(2) "bc"
}

发现,这种方法并没有什么用处。、

至于原因?“弢”这个字居然不在GB2312的编码集里面!!!!!但是有这个字的编码集(GBK, GB18030)这个函数都不支持!!!!!

既然这个不好用,也许万能的正则表达式是ok的。于是得到以下代码:

1 var_dump(preg_match_all('/([^\|])*/', 'abc弢|bc', $matches));
2 var_dump($matches);

结果:

int(2)
array(2) {
  [0]=>
  array(2) {
    [0]=>
    string(4) "abc?
    [1]=>
    string(2) "bc"
  }
  [1]=>
  array(2) {
    [0]=>
    string(1) "?
    [1]=>
    string(1) "c"
  }
}

好吧,我想多了。

现在研究一下,如何用正则描述这个场景。

参考一下,鸟哥大神的博客:分割GBK中文遭遇乱码的解决。遗憾的是,正则能力比较low的我,还是想不出来合适的正则表达式(如果有想出这个正则表达式的大神们,希望可以告诉我)。

没办法,思来想去,只好用substr了:

 1 function mb_explode($delimiter, $string, $encoding = null){
 2     $list = array();
 3     is_null($encoding) && $encoding = mb_internal_encoding();
 4     $len = mb_strlen($delimiter, $encoding);
 5     while(false !== ($idx = mb_strpos($string, $delimiter, 0, $encoding))){
 6         $list[] = mb_substr($string, 0, $idx, $encoding);
 7         $string = mb_substr($string, $idx + $len, null, $encoding);
 8     }   
 9     $list[] = $string;
10     return $list; 
11 } 

测试代码:

1 $a = 'abc弢|bc';
2 
3 var_dump(mb_explode('|', $a, 'gbk'));
4 var_dump(mb_explode('bc', $a, 'gbk'));
5 var_dump(mb_explode('弢', $a, 'gbk'));

结果:

array(2) {
  [0]=>
  string(5) "abc弢"
  [1]=>
  string(2) "bc"
}
array(3) {
  [0]=>
  string(1) "a"
  [1]=>
  string(3) "弢|"
  [2]=>
  string(0) ""
}
array(2) {
  [0]=>
  string(3) "abc"
  [1]=>
  string(3) "|bc"
}

这样就可以得到正确的结果了。

转载于:https://www.cnblogs.com/365star/p/5216677.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值