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;
}



你可能感兴趣的:(C++,c,PHP,浏览器,C#)