• 分割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"
    }

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

  • 相关阅读:
    Maven安装以及Idea安装
    EasyUi和jQuery模拟后台管理页面
    EasyUI初级入门2
    EasyUI初级入门
    JS高级
    好用的表单验证工具 vuelidate
    为页面/接口添加加载进度条
    Nuxt.js(二、解决首屏速度与SEO)
    Nuxt 的介绍与安装
    Axios及其async await封装
  • 原文地址:https://www.cnblogs.com/365star/p/5216677.html
Copyright © 2020-2023  润新知