您现在的位置: 365建站网 > 365学习 > PHP截取中文字符串(mb_substr)(截取无乱码)和获取截取字数的函数

PHP截取中文字符串(mb_substr)(截取无乱码)和获取截取字数的函数

文章来源:365jz.com     点击数:149    更新时间:2018-01-12 11:19   参与评论

PHP中,substr()函数截取带有中文字符串的话,可能会出现乱码,这是因为中西文一个字节所占有的字节数不一样,而substr的长度参数是按照字节去算的,在GB2312编码时,一个中文占2个字节,英文为1个字节,而在UTF-8编码当中,一个中文可能占有2个或3个字节,英文或半角标点占1字节。

直接使用PHP函数substr截取中文字符可能会出现乱码,主要是substr可能硬生生的将一个中文字符“锯”成两半。解决办法:

1、使用mbstring扩展库的mb_substr截取就不会出现乱码了。

2、自己书写截取函数,但效率不如用mbstring扩展库来得高。

3、如果仅是为了输出截取的串,可用如下方式实现:substr($str, 0, 30).chr(0)。

=============================

substr()函数可以分割文字,但要分割的文字如果包括中文字符往往会遇到问题,这时可以用mb_substr()/mb_strcut这个函数,mb_substr()/mb_strcut的用法与substr()相似,只是在mb_substr()/mb_strcut最后要加入多一个参数,以设定字符串的编码,但是一般的服务器都没打开php_mbstring.dll,需要在php.ini在把php_mbstring.dll打开。
举个例子:
<?php
echo mb_substr('这样一来我的字符串就不会有乱码^_^', 0, 7, 'utf-8');
?>
输出:这样一来我的字
<?php
echo mb_strcut('这样一来我的字符串就不会有乱码^_^', 0, 7, 'utf-8');
?>
输出:这样一
从上面的例子可以看出,mb_substr是按字来切分字符,而mb_strcut是按字节来切分字符,但是都不会产生半个字符的现象。


一、中文截取:mb_substr()

mb_substr( $str, $start, $length, $encoding )

$str,需要截断的字符串
$start,截断开始处,起始处为0
$length,要截取的字数
$encoding,网页编码,如utf-8,GB2312,GBK

实例:
 
<?php 
$str='365建站网:http://www.365jz.com'; 
echo mb_substr($str,0,5,'utf-8');//截取头5个字,假定此代码所在php文件的编码为utf-8 
?> 
结果显示:365建站


二、获取中文长度:mb_strlen()

mb_strlen( $str, $encoding )

$str,要计算长度的字符串
$encoding,网页编码,如utf-8,GB2312,GBK

实例:
 
<?php 
$str='365建站网:http://www.365jz.com'; 
echo mb_strlen($str,'utf-8');//假定此代码所在php文件的编码为utf-8 
?> 
结果显示:27

PHP实现中文字串截取无乱码的方法

function GBsubstr($string, $start, $length) {
if(strlen($string)>$length){
   $str=null;
   $len=$start+$length;
   for($i=$start;$i<$len;$i++){
    if(ord(substr($string,$i,1))>0xa0){
     $str.=substr($string,$i,2);
     $i++;
    }else{
     $str.=substr($string,$i,1);
    }
   }
   return $str.'...';
}else{
   return $string;
}
}
 
【实现中文字串截取无乱码的方法--适用于utf-8】
function substr_text($str, $start=0, $length, $charset="utf-8", $suffix="")
{
if(function_exists("mb_substr")){
return mb_substr($str, $start, $length, $charset).$suffix;
}
elseif(function_exists('iconv_substr')){
return iconv_substr($str,$start,$length,$charset).$suffix;
}
$re['utf-8']  = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
$re['gbk']    = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
$re['big5']   = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
preg_match_all($re[$charset], $str, $match);
$slice = join("",array_slice($match[0], $start, $length));
return $slice.$suffix;
}
dedecms中的截取函数:
/**
*  中文截取2,单字节截取模式
*  如果是request的内容,必须使用这个函数
*
* @access    public
* @param     string  $str  需要截取的字符串
* @param     int  $slen  截取的长度
* @param     int  $startdd  开始标记处
* @return    string
*/
if ( ! function_exists('cn_substrR'))
{
    function cn_substrR($str, $slen, $startdd=0)
    {
        $str = cn_substr(stripslashes($str), $slen, $startdd);
        return addslashes($str);
    }
}

/**
*  中文截取2,单字节截取模式
*
* @access    public
* @param     string  $str  需要截取的字符串
* @param     int  $slen  截取的长度
* @param     int  $startdd  开始标记处
* @return    string
*/
if ( ! function_exists('cn_substr'))
{
    function cn_substr($str, $slen, $startdd=0)
    {
        global $cfg_soft_lang;
        if($cfg_soft_lang=='utf-8')
        {
            return cn_substr_utf8($str, $slen, $startdd);
        }
        $restr = '';
        $c = '';
        $str_len = strlen($str);
        if($str_len < $startdd+1)
        {
            return '';
        }
        if($str_len < $startdd + $slen || $slen==0)
        {
            $slen = $str_len - $startdd;
        }
        $enddd = $startdd + $slen - 1;
        for($i=0;$i<$str_len;$i++)
        {
            if($startdd==0)
            {
                $restr .= $c;
            }
            else if($i > $startdd)
            {
                $restr .= $c;
            }

            if(ord($str[$i])>0x80)
            {
                if($str_len>$i+1)
                {
                    $c = $str[$i].$str[$i+1];
                }
                $i++;
            }
            else
            {
                $c = $str[$i];
            }

            if($i >= $enddd)
            {
                if(strlen($restr)+strlen($c)>$slen)
                {
                    break;
                }
                else
                {
                    $restr .= $c;
                    break;
                }
            }
        }
        return $restr;
    }
}

/**
*  utf-8中文截取,单字节截取模式
*
* @access    public
* @param     string  $str  需要截取的字符串
* @param     int  $slen  截取的长度
* @param     int  $startdd  开始标记处
* @return    string
*/
if ( ! function_exists('cn_substr_utf8'))
{
    function cn_substr_utf8($str, $length, $start=0)
    {
        if(strlen($str) < $start+1)
        {
            return '';
        }
        preg_match_all("/./su", $str, $ar);
        $str = '';
        $tstr = '';

        //为了兼容mySQL4.1以下版本,与数据库varchar一致,这里使用按字节截取
        for($i=0; isset($ar[0][$i]); $i++)
        {
            if(strlen($tstr) < $start)
            {
                $tstr .= $ar[0][$i];
            }
            else
            {
                if(strlen($str) < $length + strlen($ar[0][$i]) )
                {
                    $str .= $ar[0][$i];
                }
                else
                {
                    break;
                }
            }
        }
        return $str;
    }
}

 

如对本文有疑问,请提交到交流论坛,广大热心网友会为你解答!! 点击进入论坛


发表评论 (149人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码: 点击我更换图片
最新评论
------分隔线----------------------------