高效的中文字符串截取函数

在php中使用传统的字符串截取函数substr处理含有中文字符的字符串时会出现汉字被切断的现象。当可以使用php扩展库时,我们可以用mb_substr代替。但是该扩展库在连接时有一定的困难——linux下需重新编译php,有时并不能可做到,更何况其冗余函数较多。
在网络上可以看到很多实现此功能的函数。但算法多是循环判断,当字符串较大时效率极低。
为此这里介绍两个高效的函数:c_substr、m_substr。他们的用法完全与substr和mb_substr相同。不同之处在于:c_substr按字节计算,即一个汉字的长度为2;m_substr按字计算,即一个汉字的长度为1。可根据需要选用。

代码:

function c_substr( $str, $start=0) {
$ch = chr(127);
$p = array("/x81-xfe/","/[x01-x77]/");
$r = array("","");
if(func_num_args() > 2)
$end = func_get_arg(2);
else
$end = strlen( $str);
if( $start < 0)
$start += $end;

if( $start > 0) {
$s = substr( $str,0, $start);
if( $s[strlen( $s)-1] > $ch) {
$s = preg_replace( $p, $r, $s);
$start += strlen( $s);
}
}
$s = substr( $str, $start, $end);
$end = strlen( $s);
if( $s[ $end-1] > $ch) {
$s = preg_replace( $p, $r, $s);
$end += strlen( $s);
}
return substr( $str, $start, $end);
}

function m_substr( $str, $start) {
preg_match_all("/[x80-xff]?./", $str, $ar);
if(func_num_args() >= 3) {
$end = func_get_arg(2);
return join("",array_slice( $ar[0], $start, $end));
}else
return join("",array_slice( $ar[0], $start));
}

Published At
Categories with Web编程
Tagged with
comments powered by Disqus