/*
截取中文字符 by LAD
string cnsubstr(string $string,integer $length)
*/
function cnsubstr($string,$sublen)
{
if($sublen>=strlen($string))
{
return $string;
}
$return="";
for($i=0;$i<$sublen;$i++)
{
if(ord($string{$i})>127)
{
$return.=$string{$i}.$string{++$i};
continue;
}else{
$return.=$string{$i};
continue;
}
}
return $return;
}#end function cnsubstr
截取中文字符 by LAD
string cnsubstr(string $string,integer $length)
*/
function cnsubstr($string,$sublen)
{
if($sublen>=strlen($string))
{
return $string;
}
$return="";
for($i=0;$i<$sublen;$i++)
{
if(ord($string{$i})>127)
{
$return.=$string{$i}.$string{++$i};
continue;
}else{
$return.=$string{$i};
continue;
}
}
return $return;
}#end function cnsubstr
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);
}
或
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));
}函数c_substr、m_substr与substr用法一样
c_substr 以字节为单位
m_substr 以字为单位
Fatal error: Maximum execution time of 30 seconds exceeded我想问下上面我提到的那个错误主要是什么原因。谢谢!
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));
}?????????
chinaworker(网络混混 Hrcn.CN)
那?????????
是什么意思?不理解?!
function m_substr($str,$start) { //必须有两个参数,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)); //取出从start到end间的元素并连接成串
}else
return join("",array_slice($ar[0],$start)); //取出从start到结束的元素并连接成串
}
作者:徐祖宁在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]([\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);
}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));
}性能测试:
1、使用pear的Bench_Iterate类作为计时器
2、以循环判断的对照函数
function TrimChinese($str,$len){
$r_str="";
$i=0;
while ($i<$len){
$ch=substr($str,$i,1);
if(ord($ch)>0x80) $i++;
$i++;
}
$r_str=substr($str,0,$i);
return $r_str;
}
3、测试环境:p2/166、nt4 iis4+php4.3.1
4、测试代码:
require_once "Bench/Iterate.php";
$bench = new Bench_Iterate;$bench->run(100, "TrimChinese", $str , 1000);
$result = $bench->get();
echo "TrimChinese:".$result[mean]."<br>";$bench->run(100, "c_substr", $str , 3,1000);
$result = $bench->get();
echo "c_substr:".$result[mean]."<br>";$bench->run(100, "m_substr", $str , 3,1000);
$result = $bench->get();
echo "m_substr:".$result[mean]."<br>";$bench->run(100, "mb_substr", $str , 3,1000);
$result = $bench->get();
echo "mb_substr:".$result[mean]."<br>";
5、测试文字:本文
6、测试结果:
TrimChinese:0.058972
c_substr:0.000809
m_substr:0.000666
mb_substr:0.000458附:
function m_strlen($str) {
preg_match_all("/[\x80-\xff]?./",$str,$ar);
return count($ar[0]);
}function m_chunk_split($str,$size=64) {
preg_match_all("/[\x80-\xff]?./",$str,$ar);
$a = array_chunk($ar[0],$size);
foreach($a as $k=>$v)
$a[$k] = join("",$a[$k]);
return join("\r\n",$a);
}