php 中文字串截取有關問題?

來源:互聯網
上載者:User
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函數
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.