擷取UTF8編碼字串從首位元組開始指定寬度(非長度),
適用於字串長度有限的如新聞標題的等寬度擷取
中英文混排情況較理想. 全中文與全英文擷取後對比顯示寬度差異最大,且擷取寬度遠大越明顯.
程式碼示例
<?
/**
* @author Crazy、Ly Crazy、Ly
* @email undefined <653541412@qq.com>
* @date 2019-07-01 14:22:43
* @modifyby Crazy、Ly
*/
$str = "擷取UTF8編碼字串從首位元組開始指定寬度(非長度), 適用於字串長度有限的如新聞標題的等寬度擷取";
$ss = u8_title_substr($str,10);
echo $ss;
/**
* @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
*/
function u8_title_substr($str, $width = 0, $end = '…', $x3 = 0) {
// global $CFG; // 全域性變數儲存 x3 的值
$CFG['cf3'] = 2;
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;
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;
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結