高效的中文字串擷取函式 (轉)

amyz發表於2007-11-13
高效的中文字串擷取函式 (轉)[@more@]

高效的中文字串擷取
作者:徐祖寧

在中使用傳統的字串擷取函式substr處理含有中文字元的字串時會出現漢字被切斷的現象。當可以使用php擴充套件庫時,我們可以用mb_substr代替。但是該擴充套件庫在連線時有一定的困難——下需重新編譯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的Benchmark_Iterate類作為計時器
2、以迴圈判斷的對照函式
function TrimChinese($str,$len){
  $r_str="";
  $i=0;
  while ($i  $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+.3.1
4、測試程式碼:
require_once "Benchmark/Iterate.php";
$benchmark = new Benchmark_Iterate;

$benchmark->run(100, "TrimChinese", $str , 1000);
$result = $benchmark->get();
echo "TrimChinese:".$result[mean]."
";

$benchmark->run(100, "c_substr", $str , 3,1000);
$result = $benchmark->get();
echo "c_substr:".$result[mean]."
";

$benchmark->run(100, "m_substr", $str , 3,1000);
$result = $benchmark->get();
echo "m_substr:".$result[mean]."
";

$benchmark->run(100, "mb_substr", $str , 3,1000);
$result = $benchmark->get();
echo "mb_substr:".$result[mean]."
";
5、測試文字:本文
6、測試結果:(秒)
TrimChinese:0.058972
c_substr:0.000809
m_substr:0.000666
mb_substr:0.000458


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-982154/,如需轉載,請註明出處,否則將追究法律責任。

相關文章