php 中文字串截取問題???
因為用substr()函數截取中文字串會出現問題,所以我就上網找了一個函數,如下:
PHP code
//中文字串截取無亂碼函數function cut_str($string, $start, $length) { if(strlen($string)>$length){ $str = null; $len = $start+$length; for($i=$start;$i<$len;$i++){ if(ord(substr($string,$i,1))>0xa0){ $str.=substr($string,$i,2); $i++; }else{ $str.=substr($string,$i,1); } } return $str.'...'; }else{ return $string; }}
但是用過之後還是會出現問題,比如我截取的是“利用濾鏡及圖層樣式製作逼真的石塊字”,
PHP code
$str = "利用濾鏡及圖層樣式製作逼真的石塊字";cut_str($str,0,50);
但是效果出來了卻是這樣的:“利用濾鏡及圖層樣式製作逼真的石塊?...”,除了個問號一樣的字元,我鬱悶啊,上網查了一下,漢子在utf-8編碼中一般佔3個位元組,但是這個函數中這裡“$str.=substr($string,$i,2);”卻截取2,這是什麼意思呢??始終沒有弄明啊。。。。如果我把2改成3後,那句就會變成“利?甔?滻??鏡?及?圖?山??樣?弼??制?佽??逼?眜?的?石?壩?字...”,唉,,,真的被它搞敗了,哪位大俠救救我啊。。。。。。。。。
------解決方案--------------------
怎麼不用mb_substr()函數
------解決方案--------------------
你要確定你的編碼。截取時指定編碼。
------解決方案--------------------
它是以位元組計算的。gbk編碼。一個中文等於2個位元組。
------解決方案--------------------
當然是mb_substr了,樓主對編碼看樣不太懂。。。
utf8中文編碼2-3個字元很常見,但非ASCII字元的單位元組一定是第7位為1的,與ASCII單位元組是不衝突的,GBK碼也是類似的。
請用mb_substr,它會自動根據utf8編碼範圍識別多位元組字元的。
------解決方案--------------------
這個函數只適用於gbk編碼
探討
哈哈,研究了下手冊,剛搞定,就是你說的,確定一下編碼,但是我想知道那個函數為啥不行啊??那個貌似是php面試的答案誒。前輩能否指點一二,特別是那裡的2,utf-8中漢子明明是3-4個字元啊,而且常用的是3個字元啊。。。。。麻煩了
------解決方案--------------------
PHP code
/**************************** * subCNchar() 截取漢字 * * [$str] [要截取的字串] * [$start] [截取的起始位置] * [$length] [要截取的長度] * [$charset] [字串編碼] ****************************/function subCNchar($str, $start = 0, $length, $charset = "utf-8") { if (strlen($str) <= $length) return $str; $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/"; $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/"; $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; preg_match_all($re[$charset], $str, $match); $slice = join("", array_slice($match[0], $start, $length)); return $slice;}
------解決方案--------------------
為什麼不能在後面加上.....
echo mb_strlen($str,'utf-8')>10 ? mb_substr($str,0,10,'utf-8').'...' : $str;
------解決方案--------------------
加"..."見12樓,
如果你非要改這個函數,utf8的編碼很有規律,就是下面幾種,除ascii碼部分外,
第一個位元組都是11開頭,連續的1的個數代表了總位元組數,後續位元組都是10開頭
其中漢字基本在3個位元組的區.
知道了這個規律,寫個函數應該很容易吧?
U+007F 0xxxxxxx
U+07FF 110xxxxx 10xxxxxx
U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
U+1FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U+3FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
探討
那這個函數能不能改成utf-8的??mb_substr()貌似不能在未輸出完的字元結尾加上“...”誒,這樣影響效果,求解
------解決方案--------------------
你可以用mb_strimwidth函數