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;
}

解决方案 »

  1.   

    谢谢楼上的帮助,但是这个函数只是可以将中英文截取需要的个数,而对我现在的需求而言还不能满足。因为我需要最多37个字符,在中英文混合的情况下,具体字符数是不固定的,如果要用这个函数就要有一段程序判断在指定字符串情况下,到底37个英文字符的位置是多少个中文字符加多少英文字符然后再传递给msubstr截取。比如“aa中国”,要是截取3个字符,函数就返回“aa中”,我要的效果是截取4个字符的时候返回“aa中”。
    所以当前情况下或者有方法判断一段字符串中37个英文字符的宽度有几个中文几个英文加起来,这涉及到怎样判断中英文个数,要么就是就一个函数能在给定参数4的情况下返回“aa中”。请大家帮助
      

  2.   

    在浏览器中,一个汉字占两个西文字符的位置,这个说法是针对等宽字体而言的
    在此前提下针对 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>
      

  3.   

     text-overflow:ellipsis; 貌似IE only.
      

  4.   

    比如“aa中国”,要是截取3个字符,函数就返回“aa中”,我要的效果是截取4个字符的时候返回“aa中”。问个问题,如果截取3个字符,函数应该返回什么才是你想要的?
    如果判断到不够截取,是放弃,就是截取2个字符,和3个字符都是aa吗?
    还是aa然后中文被截一半变乱码吗?
    所以上面的函数是避免了这个问题。所以用中文的字符量为标准。
      

  5.   

    如果没有mbstring扩展,装个mbstring吧。