php计算字符串截取的问题
PHP中文网
PHP中文网 2017-04-11 10:30:44
[PHP讨论组]

我页面上有个字符串过长需要用省略号代替的功能,现在我用strlen和substr实现,发现中文和英文截取文字长度不一样,导致中文截取的过少,英文的截取的和设置的长度的一样。有没有什么好的方法统一中文和英文一样!表示无语啊!

PHP中文网
PHP中文网

认证0级讲师

全部回复(6)
天蓬老师

php中编码是UTF-8的话占3个字节;是GB2312的话占2个字节。推荐你把所有字符设置成同一种编码字符处理。php除了strlensubstr之外,还有带mb_开头的啊!可以指定字符串编码格式例如mb_strlen和mb_substr

$len = mb_strlen($string, 'UTF-8');
$newString = $len>60?mb_substr($string, 0, 60, 'UTF-8'):$string;

试试看

PHPz

让多余的字符串显示为省略号,截取的方式是一种很落后的方式,而且字符串截取对于中文和英文截取结果不一样。HTML5中可以直接通过css来控制:

overflow: hidden;  //溢出部分影藏
white-space: nowrap;  //文本不进行换行
text-overflow: ellipsis;   //当文本溢出包含元素时显示省略号

这三个组合使用即可。

黄舟
    /**
     * 字符串截取方法(支持中英文,截取长度包含省略符)
     * @param  string $string   字符串
     * @param  integer $length  截取长度
     * @param  string $dot      省略符
     * @param  string $charset  编码
     * @return string
     */
    function strCut($string, $length, $dot = '...', $charset = 'UTF-8') {
        $charset = 'UTF-8';
        $strlen = strlen($string);
        if($strlen <= $length) return $string;
        $string = str_replace(
            array(' ','&nbsp;', '&', '"', '\'', '“', '”', '—', '<', '>', '·', '…'), 
            array(' ',' ', '&', '"', "'", '“', '”', '—', '<', '>', '·', '…'),
            $string
        );
        $strcut = '';
        if (strtolower($charset) == 'utf-8') {
            $length = intval($length-strlen($dot)-$length/3);
            $n = $tn = $noc = 0;
            while ($n < strlen($string)) {
                $t = ord($string[$n]);
                if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
                    $tn = 1; $n++; $noc++;
                } elseif(194 <= $t && $t <= 223) {
                    $tn = 2; $n += 2; $noc += 2;
                } elseif(224 <= $t && $t <= 239) {
                    $tn = 3; $n += 3; $noc += 2;
                } elseif(240 <= $t && $t <= 247) {
                    $tn = 4; $n += 4; $noc += 2;
                } elseif(248 <= $t && $t <= 251) {
                    $tn = 5; $n += 5; $noc += 2;
                } elseif($t == 252 || $t == 253) {
                    $tn = 6; $n += 6; $noc += 2;
                } else {
                    $n++;
                }
                if ($noc >= $length) {
                    break;
                }
            }
            if ($noc > $length) {
                $n -= $tn;
            }
            $strcut = substr($string, 0, $n);
            $strcut = str_replace(
                array('∵', '&', '"', "'", '“', '”', '—', '<', '>', '·', '…'), 
                array(' ', '&', '"', '\'', '“', '”', '—', '<', '>', '·', '…'),
                $strcut
            );
        } else {
            $dotlen = strlen($dot);
            $maxi = $length - $dotlen - 1;
            $current_str = '';
            $search_arr = array('&',' ', '"', "'", '“', '”', '—', '<', '>', '·', '…','∵');
            $replace_arr = array('&','&nbsp;', '"', '\'', '“', '”', '—', '<', '>', '·', '…',' ');
            $search_flip = array_flip($search_arr);
            for ($i = 0; $i < $maxi; $i++) {
                $current_str = ord($string[$i]) > 127 ? $string[$i].$string[++$i] : $string[$i];
                if (in_array($current_str, $search_arr)) {
                    $key = $search_flip[$current_str];
                    $current_str = str_replace($search_arr[$key], $replace_arr[$key], $current_str);
                }
                $strcut .= $current_str;
            }
        }
        return $strcut.$dot;
    }

推荐使用这个方法来避免一下尴尬:

(1) substr截取中文会出现乱码的情况:

$string = '中文字符中文字符';
var_dump(substr($string, 0, 10));

结果:string(10) "中文字�"
原因:中文占3个字符,substr可能会把某个中文截取了一部分,使中文乱码。

(2) mb_substr截取会出现字符太长的情况:

$string = '中文字符englishword';
var_dump(mb_substr($string, 0, 10));

结果:string(18) "中文字符englis"
原因:中文占3个字符,输出结果的字符串实际占18个字符,并不是期望的10个字符。

使用情景:微信支付商品名称有128个字符限制,在UTF-8编码下,中英文字符的总字符长度要控制在128个以内,个人觉得用这个方法比较合适。

阿神

text-overflow:ellipsis

PHP中文网
string mb_strimwidth ( string $str , int $start , int $width [, string $trimmarker = "" [, string $encoding = mb_internal_encoding() ]] )

PHP提供的这个函数看起来可以满足你的要求. $trimmarker 是如果长度超了, 后面添加的...这三字符.

天蓬老师

baidu就可以了吧,我基本都是这样解决的。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号