截取 UTF8 编码字符串从首字节开始指定宽度 (非长度)

截取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 协议》,转载必须注明作者和本文链接
当你的才华撑不起你的野心,那就静下来学习
crazyly
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!