扫码关注官方订阅号
我页面上有个字符串过长需要用省略号代替的功能,现在我用strlen和substr实现,发现中文和英文截取文字长度不一样,导致中文截取的过少,英文的截取的和设置的长度的一样。有没有什么好的方法统一中文和英文一样!表示无语啊!
认证0级讲师
在php中编码是UTF-8的话占3个字节;是GB2312的话占2个字节。推荐你把所有字符设置成同一种编码字符处理。php除了strlen和substr之外,还有带mb_开头的啊!可以指定字符串编码格式例如mb_strlen和mb_substr
php
UTF-8
GB2312
strlen
substr
mb_
$len = mb_strlen($string, 'UTF-8'); $newString = $len>60?mb_substr($string, 0, 60, 'UTF-8'):$string;
试试看
让多余的字符串显示为省略号,截取的方式是一种很落后的方式,而且字符串截取对于中文和英文截取结果不一样。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(' ',' ', '&', '"', '\'', '“', '”', '—', '<', '>', '·', '…'), 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('&',' ', '"', '\'', '“', '”', '—', '<', '>', '·', '…',' '); $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可能会把某个中文截取了一部分,使中文乱码。
string(10) "中文字�"
(2) mb_substr截取会出现字符太长的情况:
$string = '中文字符englishword'; var_dump(mb_substr($string, 0, 10));
结果:string(18) "中文字符englis"原因:中文占3个字符,输出结果的字符串实际占18个字符,并不是期望的10个字符。
string(18) "中文字符englis"
使用情景:微信支付商品名称有128个字符限制,在UTF-8编码下,中英文字符的总字符长度要控制在128个以内,个人觉得用这个方法比较合适。
使用情景:
text-overflow:ellipsis
string mb_strimwidth ( string $str , int $start , int $width [, string $trimmarker = "" [, string $encoding = mb_internal_encoding() ]] )
PHP提供的这个函数看起来可以满足你的要求. $trimmarker 是如果长度超了, 后面添加的...这三字符.
baidu就可以了吧,我基本都是这样解决的。
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
在
php中编码是UTF-8的话占3个字节;是GB2312的话占2个字节。推荐你把所有字符设置成同一种编码字符处理。php除了strlen和substr之外,还有带mb_开头的啊!可以指定字符串编码格式例如mb_strlen和mb_substr试试看
让多余的字符串显示为省略号,截取的方式是一种很落后的方式,而且字符串截取对于中文和英文截取结果不一样。HTML5中可以直接通过css来控制:
这三个组合使用即可。
推荐使用这个方法来避免一下尴尬:
(1) substr截取中文会出现乱码的情况:
结果:
string(10) "中文字�"原因:中文占3个字符,
substr可能会把某个中文截取了一部分,使中文乱码。(2) mb_substr截取会出现字符太长的情况:
结果:
string(18) "中文字符englis"原因:中文占3个字符,输出结果的字符串实际占18个字符,并不是期望的10个字符。
使用情景:微信支付商品名称有128个字符限制,在UTF-8编码下,中英文字符的总字符长度要控制在128个以内,个人觉得用这个方法比较合适。text-overflow:ellipsis
PHP提供的这个函数看起来可以满足你的要求. $trimmarker 是如果长度超了, 后面添加的...这三字符.
baidu就可以了吧,我基本都是这样解决的。