[PHP]截取中文字符串(支持多种编码)优化版(doubi版)
12345 - 2014/05/26这是原来的代码,本身就不错
PHP 截取中文字符串(支持多种编码)
通过PHP 截取中文字符串(支持多种编码) - 开源中国社区.
我改的增加了一些计算和是否添加尾缀的判断,所以性能上会略差,欢迎吐槽
/** * 字符串截取,支持中文和其他编码 * * @param string $str 需要转换的字符串 * @param string $start 开始位置 * @param string $length 截取长度 * @param string $charset 编码格式 * @param string $suffix 截断字符串后缀 * @return string */ function substr_ext($str, $start=0, $length, $charset="utf-8", $suffix="") { //处理尾缀,由于该参数比较特殊,只能分开处理 if(function_exists("mb_strlen")) if (((mb_strlen($str)-$start)<$length)) $suffix = ''; //如果字符串没超出长度不添加尾缀 if(function_exists("mb_substr")){ return mb_substr($str, $start, $length, $charset).$suffix; } //我们的服务器支持mb_substr 所以直接注释掉下面的内容 elseif(function_exists('iconv_substr')){ if (function_exists('iconv_strlen')) if (((iconv_strlen($str)-$start)<$length)) $suffix = ''; //如果字符串没超出长度不添加尾缀 return iconv_substr($str,$start,$length,$charset).$suffix; } //不支持mb_substr 或者 iconv_substr的服务器运行以下低效率语句 $length +=$length; //接下来的过程中一个中文要占2个字符所以length加倍 //$reAscii = "/[\x01-\x7f]|"; 这句暂时没有用。可以删掉 $re['utf-8'] = "[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; $re['gb2312'] = "[\xb0-\xf7][\xa0-\xfe]/"; $re['gbk'] = "[\x81-\xfe][\x40-\xfe]/"; $re['big5'] = "[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; //preg_match_all($reAscii.$re[$charset], $str, $match); $str = mb_convert_encoding($str, 'utf-8'); //先转成utf-8才能进行之后的操作 $newStr = StringToArray($str); //字面意思 ,将字符串分离为数组 $strLen = 0; $outStr = ""; foreach($newStr as $key => $val){ //计算长度,一个中文占2个字符 if ($key<$start) continue; if(preg_match("/".$re[$charset],$val)) $strLen +=2; else ++$strLen; if ($strLen<$length) //如果没超长,往新的字符串里放文字 $outStr = $outStr.$val; } if ($strLen-$start<$length) $suffix = ""; //如果没超出字符限制不添加尾缀 //$slice = join("",array_slice($match[0], $start, $length)); return $outStr.$suffix; } /** * 把字符串转成数组,支持汉字,只能是utf-8格式的 * @param $str * @return array */ function StringToArray($str) { $result = array(); $len = strlen($str); $i = 0; while($i < $len){ $chr = ord($str[$i]); if($chr == 9 || $chr == 10 || (32 <= $chr && $chr <= 126)) { $result[] = substr($str,$i,1); $i +=1; }elseif(192 <= $chr && $chr <= 223){ $result[] = substr($str,$i,2); $i +=2; }elseif(224 <= $chr && $chr <= 239){ $result[] = substr($str,$i,3); $i +=3; }elseif(240 <= $chr && $chr <= 247){ $result[] = substr($str,$i,4); $i +=4; }elseif(248 <= $chr && $chr <= 251){ $result[] = substr($str,$i,5); $i +=5; }elseif(252 <= $chr && $chr <= 253){ $result[] = substr($str,$i,6); $i +=6; } } return $result; }
转载保留版权:http://haipz.com/blog/i/2974 - 海胖博客
好负责,除非必要,不然我都懒得注释,我喜欢~