<?php
/**
* @brief 简洁高效的字符串截取函数 (支持 CJK字符)
*
* 只是简单判断了高位部分的ASCII值, 能应付绝大多数正规的中英文混合字符串
* 不支持 4字节或3字节的 utf 编码
*
* 要点: 修正双字节中错位的 off 值 / len 值 (注意参数 $len 缺省值为 -1的用意)
* 用法和 substr() 一样, 针对 GBK 码的低位(0x40开始)可能有问题
*/
function my_substr($str, $off, $len = -1)
{
$mlen = strlen($str);
/* 第0步: 参数安全检查与修正 */
if ($off < 0)
$off += $mlen;
if ($off > $mlen)
$off = 0;
/* 第1步: $off 修正, 倒寻 */
if ($off > 0)
{
$fix = $off;
$mb = false;
do
{
$ch = ord($str{$fix--});
if ($ch < 0x80)
break;
$mb = true;
}
while ($fix);
if ($mb)
{
$fix = ($off - $fix);
if ($fix & 1)
{
$off--;
$len++;
}
}
}
/* 第2步: $len 修正, 同上 */
if ($len <= 0 || ($len + $off) >= $mlen)
{
$len = $mlen - $off;
}
else
{
$fix = $off + $len;
$mb = false;
do
{
$ch = ord($str{$fix--});
if ($ch < 0x80)
break;
$mb = true;
}
while ($fix > $off);
if ($mb)
{
$fix = $fix - $off;
if (!($fix & 1))
$len--;
}
}
return substr($str, $off, $len);
}
/** 超级暴力有效的中文截取函数 */
function my_substr2($str, $off, $len = 0)
{
$mlen = strlen($str);
/* 第1步: 暴力修正 off 值 */
if ($off < 0)
$off += $mlen;
if ($off > $mlen)
$off = 0;
for ($i = 0; $i < $off ; $i++)
{
$ch = ord($str{$i});
if ($ch > 0xa0)
$i++;
}
/* 第1步: 暴力修正 len 值 */
$off = $i;
if ($len <= 0 || $len > ($mlen - $off))
$len = ($mlen - $off);
$end = $off + $len;
while ($i < $end)
{
$ch = ord($str{$i++});
if ($ch > 0xa0)
$i++;
}
return substr($str, $off, $i - $off);
}
此文章由 http://www.ositren.com 收集整理 ,地址为:
http://www.ositren.com/htmls/67181.html