程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 分割gbk中文出現亂碼的問題解決,分割gbk中文亂碼

分割gbk中文出現亂碼的問題解決,分割gbk中文亂碼

編輯:關於PHP編程

分割gbk中文出現亂碼的問題解決,分割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"
}

這樣就可以得到正確的結果了。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved