首页 > php函数 > 发一个刚编的暴力版/温柔版中文截取函数

发一个刚编的暴力版/温柔版中文截取函数

推荐使用暴力版的, 安全可靠; 温柔版的从程序编写的角度看比较高效. 呵呵

基本原理是修正 off, len 可能的错位, 温柔版是从 off 往前倒寻, 寻到第一个 <0xa0 的字符认为是普通字符, 搜寻结束, 根据次数判定是否有错位...

<?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.phprm.com/function/6341aaaf95ba95ce0736d4107061fed4.html

转载随意!带上文章地址吧。

标签:none

发表留言