ThinkPHP框架中有一个截取函数比较不错/**
+----------------------------------------------------------
* 字符串截取,支持中文和其他编码
+----------------------------------------------------------
* @static
* @access public
+----------------------------------------------------------
* @param string $str 需要转换的字符串
* @param string $start 开始位置
* @param string $length 截取长度
* @param string $charset 编码格式
* @param string $suffix 截断显示字符
+----------------------------------------------------------
* @return string
+----------------------------------------------------------
*/
function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true)
{
if(function_exists("mb_substr"))
{
if ($suffix && strlen($str)>$length)
return mb_substr($str, $start, $length, $charset)."...";
else
return mb_substr($str, $start, $length, $charset);
}
elseif(function_exists('iconv_substr'))
{
if ($suffix && strlen($str)>$length)
return iconv_substr($str,$start,$length,$charset)."...";
else
return iconv_substr($str,$start,$length,$charset);
} $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));
if($suffix)
return $slice."…";
return $slice;
}
+----------------------------------------------------------
* 字符串截取,支持中文和其他编码
+----------------------------------------------------------
* @static
* @access public
+----------------------------------------------------------
* @param string $str 需要转换的字符串
* @param string $start 开始位置
* @param string $length 截取长度
* @param string $charset 编码格式
* @param string $suffix 截断显示字符
+----------------------------------------------------------
* @return string
+----------------------------------------------------------
*/
function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true)
{
if(function_exists("mb_substr"))
{
if ($suffix && strlen($str)>$length)
return mb_substr($str, $start, $length, $charset)."...";
else
return mb_substr($str, $start, $length, $charset);
}
elseif(function_exists('iconv_substr'))
{
if ($suffix && strlen($str)>$length)
return iconv_substr($str,$start,$length,$charset)."...";
else
return iconv_substr($str,$start,$length,$charset);
} $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));
if($suffix)
return $slice."…";
return $slice;
}
所以当前情况下或者有方法判断一段字符串中37个英文字符的宽度有几个中文几个英文加起来,这涉及到怎样判断中英文个数,要么就是就一个函数能在给定参数4的情况下返回“aa中”。请大家帮助
在此前提下针对 utf-8 编码的中西文混合字符串的显示宽度(西文为1、中文为2)有如下计算公式
(按字节计的长度 - 按字计的长度) / 2 + 按字计的长度比如 aa中国
按字节计的长度为 8
按字计的长度为 4
带入得 (8-4)/2+4 = 6
即 6 个显示单位如果你需要先指定显示长度,就需要做循环试探了
其实 css 已经提供了更好的解决方案<style>
body{
background-color:#f4f4f4;
font-size:12px;
}
div.test{
width:200px;
height:60px;
border:1px solid red;
border-top:4px solid red;
padding:10px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
}
</style>
<div class="test">DIV+CSS模板、后台模板、图片图标下载,CSS代码实例、CSS导航菜单、CSS图表
</div>
如果判断到不够截取,是放弃,就是截取2个字符,和3个字符都是aa吗?
还是aa然后中文被截一半变乱码吗?
所以上面的函数是避免了这个问题。所以用中文的字符量为标准。