PHP UTF-8 等寬度截取中英文字符

網站需要截取等寬新聞標題,對於GB編碼的截取函數網上很多,沒找到有適合UTF-8編碼的。 考慮到UTF-8是1-4字節變長編碼,雖然中文都是3字節,爲了以後方便決定自己寫個。

截取的變量是寬度width而不是長度length。不同中英文(包括數字)字型搭會有不同顯示效果,在不同顯示器上相同字型也可能會有不同效果。 需要根據實際修改 x3變量的值,x3越大則3字節編碼(如中文)字符就取得越少。 全中文與全英文/數字截取顯示寬度差異最大,且截取寬度值越大越明顯。 中英文混排情況時差異較小。



/**
* 截取UTF8編碼字符串從首字節開始指定寬度(非長度), 適用於字符串長度有限的如新聞標題的等寬度截取
* 中英文混排情況較理想. 全中文與全英文截取後對比顯示寬度差異最大,且截取寬度遠大越明顯.
* @param string $str UTF-8 encoding
* @param int[option] $width 截取寬度
* @param string[option] $end 被截取後追加的尾字符
* @param float[option] $x3<p>
* 3字節(中文)字符相當於希臘字母寬度的係數coefficient(小數)
* 中文通常固定用宋體,根據ascii字符字體寬度設定,不同瀏覽器可能會有不同顯示效果</p>
*
* @return string
* @author waiting
* http://waiting.iteye.com
*/
function u8_title_substr($str, $width = 0, $end = '...', $x3 = 0) {
global $CFG; // 全局變量保存 x3 的值
if ($width <= 0 || $width >= strlen($str)) {
return $str;
}
$arr = str_split($str);
$len = count($arr);
$w = 0;
$width *= 10;

// 不同字節編碼字符寬度係數
$x1 = 11; // ASCII
$x2 = 16;
$x3 = $x3===0 ? ( $CFG['cf3'] > 0 ? $CFG['cf3']*10 : $x3 = 21 ) : $x3*10;
$x4 = $x3;

// http://zh.wikipedia.org/zh-cn/UTF8
for ($i = 0; $i < $len; $i++) {
if ($w >= $width) {
$e = $end;
break;
}
$c = ord($arr[$i]);
if ($c <= 127) {
$w += $x1;
}
elseif ($c >= 192 && $c <= 223) { // 2字節頭
$w += $x2;
$i += 1;
}
elseif ($c >= 224 && $c <= 239) { // 3字節頭
$w += $x3;
$i += 2;
}
elseif ($c >= 240 && $c <= 247) { // 4字節頭
$w += $x4;
$i += 3;
}
}

return implode('', array_slice($arr, 0, $i) ). $e;
}


發佈了8 篇原創文章 · 獲贊 0 · 訪問量 2479
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章