PHP截取字符串含中英文混合字符的3种方法实例详解

jerry PHP 2015年08月28日 收藏

实例一

////////////////////////////////////////////////////////////////////
// PHP截取中英文及标点符号混合的字符串函数(绝对不会出现乱码)
// 本程序在utf-8、gb2312中测试通过。使用者自行测试big5。
// 函数 left( 源字符串, 截取指定的字符串个数, 编码(可省略,默认为utf-8) )
////////////////////////////////////////////////////////////////////
function left($str, $len, $charset="utf-8")
{
    //如果截取长度小于等于0,则返回空
    if( !is_numeric($len) or $len <= 0 )
    {
        return "";
    }
    //如果截取长度大于总字符串长度,则直接返回当前字符串
    $sLen = strlen($str);
    if( $len >= $sLen )
    {
        return $str;
    }
 
    //判断使用什么编码,默认为utf-8
    if ( strtolower($charset) == "utf-8" )
    {
        $len_step = 3; //如果是utf-8编码,则中文字符长度为3  
    }else{
        $len_step = 2; //如果是gb2312或big5编码,则中文字符长度为2
    } 
    //执行截取操作
    $len_i = 0; 
    //初始化计数当前已截取的字符串个数,此值为字符串的个数值(非字节数)
    $substr_len = 0; //初始化应该要截取的总字节数
    for( $i=0; $i < $sLen; $i++ )
    {
        if ( $len_i >= $len ) break; //总截取$len个字符串后,停止循环
        //判断,如果是中文字符串,则当前总字节数加上相应编码的中文字符长度
        if( ord(substr($str,$i,1)) > 0xa0 )
        {
            $i += $len_step - 1;
            $substr_len += $len_step;
        }else{ //否则,为英文字符,加1个字节
            $substr_len ++;
        }
    $len_i ++;
    }
    $result_str = substr($str,0,$substr_len );
    return $result_str;
}
////////////////////////////////////////////////////////////////////
// 调用示例
////////////////////////////////////////////////////////////////////
$str = "空格 也算一个字符"; 
echo "截取后的字符串:".left($str,14); 
?>

 

实例二


首先是支持gb2312,gbk,big三种编码。 以下是代码:
$len = 19;
$text = "怎么将新闻的很长的标题只显示前面一些字,后面用…..来代替?";

echo strlen($text)<=$len ? $text : (substr($text,0,$len).chr(0)."….");

chr(0)不是null null是什么都没有,而chr(0)的值是0。 表示成16进制是0×00,表示成二进制是00000000 虽然chr(0)不会显示出什么,但是他是一个字符。 当汉字被截断时,根据编码规则他总是要把后边的其他字符拉过来一起作为汉字解释,这就是出现乱码的原因。 而值为0×81到0xff与0×00组合始终都显示为“空” 根据这一特点,在substr的结果后面补上一个chr(0),就可以防止出现乱码了 注: 编码 第一字节 第二字节 gb2312 0xa1-0xf7 0xa1-0xfe gbk 0×81-0xfe 0×81-0xfe 0×40-0x7e big5 0xa1-0xf7 0×81-0xfe 0×40-0x7e 其次这个是网上搜索的,支持utf-8编码,原作者不详:

function subString_UTF8($str, $start, $lenth)
    {
        $len = strlen($str);
        $r = array();
        $n = 0;
        $m = 0;
        for($i = 0; $i &lt; $len; $i++) {
            $x = substr($str, $i, 1);
            $a  = base_convert(ord($x), 10, 2);
            $a = substr(&#39;00000000&#39;.$a, -8);            if ($n &lt; $start){
                if (substr($a, 0, 1) == 0) {
                }elseif (substr($a, 0, 3) == 110) {
                    $i += 1;
                }elseif (substr($a, 0, 4) == 1110) {
                    $i += 2;
                }
                $n++;
            }else{
                if (substr($a, 0, 1) == 0) {
                    $r[ ] = substr($str, $i, 1);
                }elseif (substr($a, 0, 3) == 110) {
                    $r[ ] = substr($str, $i, 2);
                    $i += 1;
                }elseif (substr($a, 0, 4) == 1110) {
                    $r[ ] = substr($str, $i, 3);
                    $i += 2;
                }else{
                    $r[ ] = &#39;&#39;;                }
                if (++$m &gt;= $lenth){
                    break;
                }
            }
        }
        return $r;
    } // End subString_UTF8;}// End String

#由于此函数返回的是一个数组,因此要配合join函数来显示字符串:
#join('',subString_UTF8($str, $start, $lenth));
#在页面显示的时候还可以在此语句后面连一个"…"


实例三


PHP截取中文字符串有时会出现乱码
一下代码使用三种方式解决乱码问题

/******************************************************************
 * 程序一:PHP截取中文字符串方法
* 截取中文字符串时出现乱码
****************************************************************/
function msubstr($str, $start, $len) {
    $tmpstr = "";
    $strlen = $start + $len;
    for($i = 0; $i < $strlen; $i++) {
        if(ord(substr($str, $i, 1)) > 0xa0) {
            $tmpstr .= substr($str, $i, 2);
            $i++;
        } else
            $tmpstr .= substr($str, $i, 1);
    }
    return $tmpstr;
}
echo msubstr($arr, 0, 15);
echo "<br><hr><br>";
/******************************************************************
 * PHP截取UTF-8字符串,解决半字符问题。
* 英文、数字(半角)为1字节(8位),中文(全角)为3字节
* @return 取出的字符串, 当$len小于等于0时, 会返回整个字符串
* @param $str 源字符串
* $len 左边的子串的长度
****************************************************************/
function utf_substr($str,$len)
{
    for($i=0;$i<$len;$i++)
    {
        $temp_str=substr($str,0,1);
        if(ord($temp_str) > 127)
            {
            $i++;
            if($i<$len)
            {
            $new_str[]=substr($str,0,3);
            $str=substr($str,3);
            }
    }
    else
    {
        $new_str[]=substr($str,0,1);
        $str=substr($str,1);
}
}
return join($new_str);
}
echo utf_substr($arr, 39);
echo "<br><hr><br>";
/******************************************************************
 * PHP截取UTF-8字符串,解决半字符问题。
* 截取utf-8字符串,截取后,用 ...代替被截取的部分
* $length 左边的子串的长度
****************************************************************/
function cutstr($string, $length) {
    preg_match_all("/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/", $string, $info);
    for($i=0; $i<count($info[0]); $i++) {
        $wordscut .= $info[0][$i];
        $j = ord($info[0][$i]) > 127 ? $j + 2 : $j + 1;
        if ($j > $length - 3) {
            return $wordscut." ...";
        }
    }
    return join('', $info[0]);
}
echo cutstr($arr,14);
echo "<br><hr><br>";
?>