防止截错中文字符的自定义函数?
function c_substr($str,$start=0) {
$ch = chr(127);
$p = array("/[\x81-\xfe]([\x81-\xfe]|[\x40-\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);
}
$t = "我那个csubstr只能从0截取到某个字符";
echo c_substr($t,2);
echo c_substr($t,2,5);
echo c_substr($t,2,-4);
echo c_substr($t,-5);
$ch = chr(127);
$p = array("/[\x81-\xfe]([\x81-\xfe]|[\x40-\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);
}
$t = "我那个csubstr只能从0截取到某个字符";
echo c_substr($t,2);
echo c_substr($t,2,5);
echo c_substr($t,2,-4);
echo c_substr($t,-5);
function mysubstr($txt, $num)
{
if(strlen($txt)>$num)
{
$txt = substr($txt, 0, $num-4) ;
$txt .= chr(0) . "
" ;
}
return $txt ;
}
{
if(strlen($txt)>$num)
{
$txt = substr($txt, 0, $num-4) ;
$txt .= chr(0) . "
" ; }
return $txt ;
}
function cutstr($string,$len)
{
if(strlen($string)>$len) {
for $i=0; $i<$len; $i++){
$strcut.= ord($string[$i]>127) ? $string[$i].$string[++$i] : $string[$i];}
return $strcut."
..";
}else{
return $strcut;}
}
$str='这个是discuz用的.中英文均可.但中文占两个字符.';
cutstr($str,6)='这个是
..';
{
if(strlen($string)>$len) {
for $i=0; $i<$len; $i++){
$strcut.= ord($string[$i]>127) ? $string[$i].$string[++$i] : $string[$i];}
return $strcut."
.."; }else{
return $strcut;}
}
$str='这个是discuz用的.中英文均可.但中文占两个字符.';
cutstr($str,6)='这个是
..';
cutstr和mysubstr函数适用于简单的截断文字的场合,比如页面中的标题列表
其实并不需要知道一个汉字是否被截断了,所以cutstr的效率就不如mysubstr了
c_substr函数适用于需要精确的截取的场合,不要看他的代码较多但是效率一点都不低。
经测试,他的运行时间是mb_substr的三倍,属于同一数量级。而且原串的长度不影响运行时间。
而与cutstr函数一样采用逐字判断算法的函数都有运行时间随原串增长而增长的毛病
c_substr不像网络上流传的其它版本,并不依靠逐字节遍历. 基本原理是通过定义 gb2312 编码下一个完整汉字的特征
/[\x81-\xfe]([\x81-\xfe]|[\x40-\xfe])/" 和一个英文字母的特征 "/[\x01-\x77]/" 进行匹配,从而判断需要截取的开始部分和结束部分是否为半个汉字。如果不是,把它之前的所有完整汉字和完整英文字母用preg_replace()去掉,最后跳过余下不完整的部分(加上它们的长度)。
而且,此代码可以支持substr原有的各种参数,包括负数和不完全参数;
不过,当文本中包含扩展字符集GBK中的汉字时,头尾会出现乱码。
/*
* Code By 唠叨
*
* 根据 唠叨老大 以前发在CSDN的代码添加了点点东西
* @todo 中文截取,支持gb2312,gbk,utf-8,big5
*
* @param string $str 要截取的字串
* @param int $start 截取起始位置
* @param int $length 截取长度
* @param string $charset utf-8|gb2312|gbk|big5 编码
* @param $suffix 是否加尾缀
*
*/
function CsubStr($str, $start=0, $length=20, $suffix='', $charset="utf-8")
{
if(@function_exists("mb_substr"))
{
$slice = @mb_substr($str, $start, $length, $charset);
if( mb_strlen($str,$charset) > $start+$length )$slice.=$suffix;
Return $slice;
}
$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
//简化后为
//$re['utf-8'] = "/[\x00-\x7f]|[\xc0-\xff][\x80-\xbf]+/";
$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
preg_match_all($re[$charset], $str, $match);
$slice = @join("",array_slice($match[0], $start, $length));
if( strlen($str) > $start+$length )$slice.=$suffix;
Return $slice;
}//End Function
* Code By 唠叨
*
* 根据 唠叨老大 以前发在CSDN的代码添加了点点东西
* @todo 中文截取,支持gb2312,gbk,utf-8,big5
*
* @param string $str 要截取的字串
* @param int $start 截取起始位置
* @param int $length 截取长度
* @param string $charset utf-8|gb2312|gbk|big5 编码
* @param $suffix 是否加尾缀
*
*/
function CsubStr($str, $start=0, $length=20, $suffix='', $charset="utf-8")
{
if(@function_exists("mb_substr"))
{
$slice = @mb_substr($str, $start, $length, $charset);
if( mb_strlen($str,$charset) > $start+$length )$slice.=$suffix;
Return $slice;
}
$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
//简化后为
//$re['utf-8'] = "/[\x00-\x7f]|[\xc0-\xff][\x80-\xbf]+/";
$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
preg_match_all($re[$charset], $str, $match);
$slice = @join("",array_slice($match[0], $start, $length));
if( strlen($str) > $start+$length )$slice.=$suffix;
Return $slice;
}//End Function
浙公网安备 33010602011771号