zoukankan      html  css  js  c++  java
  • 按指定长度截取中英文混合字符串

    PHP对中文字符串的指定长度截取一直都是个痛,原因是中文是多字节的,容易截出乱码。对中文英文混合字符串指定长度截取更是不好解决,但只要认真分析还是可以解决的。看本函数:

    <?php
    /**
     * 功能:按指定长度截取中英文混合字符串
     * @param  string     待截取的字符串
     * @param  cnNum      需要截取相当于cnNum个汉字个数的长度
     * @param  start      可选 起始截取位置(默认0,即从开头开始截取)
     * @param  ifEllipsis 可选 返回的字符串末尾是否需要 .. 点点连接:true是(默认);false否;
     * @param  charset    可选 字符编码:支持 utf-8(默认) 和 gbk
     * @return 返回截取后的字符串
     * @author martinzhang
     */
    function mbSubstrMixStr($string, $cnNum, $start=0, $ifEllipsis=true, $charset='utf-8'){
        $start      = $start == '' ?  0 : $start;
        $ifEllipsis = $ifEllipsis===true ? true : false;
        $charset    = $charset=='' ? 'utf-8' : $charset;
        $code2Len   = array('gbk'=>2,'utf-8'=>3);                //编码对应每汉字长度(单位:字节)
        $lenString  = mb_strlen($string);                        //字符串总长度(单位:字节)
        $LenSplit   = $cnNum * $code2Len[strtolower($charset)];  //需求截取长度(单位:字节)
        $spaceLen   = $cnNum * 2;                                //需求占位(注:每个英文字符为1个占位,每个汉字为2个占位)
        if($lenString <= $LenSplit){
            return $string;
        }else{        
            for($i=-1;$i<=$spaceLen;$i++){
                $len = $cnNum + $i;                              //本轮需要截取字符个数
                $str=mb_substr($string,$start,$len,$charset);
                if(strtolower($charset)=='utf-8'){
                    //如果是utf-8编码
                    @preg_match_all("/([x{4e00}-x{9fa5}{}¥¨±·×÷ˇˉ‐—―‖‘’“”…ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ∈∏∑√∝∞∠∥∧∨∩∪∫∮∴∵∶∷∽≈≌≠≡≤≥≮≯⊙⊥⌒①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛❶❷❸❹❺❻❼❽❾❿、。〃々〈〉《》「」『』【】〔〕〖〗〝〞㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩︰︴︵︶︷︸︹︺︻︼︽︾︿﹀﹁﹂﹃﹄﹉﹊﹋﹌﹍﹎﹏﹑﹔﹕﹖﹙﹚﹛﹜﹟﹠﹡﹢﹣﹤﹦﹨﹩﹪﹫!"'()+,-/:;<=>?[]_`|~ ̄§×ΘΨ‖‥…№℡←↑→↓↖↗↘↙√∮⊕⊙⊿╱╲▁▂▃▄▅▆▇█▏▔▕■□▲△▼▽◆◇○◎●◢◣◤◥☀☂☃★☆☉☋☍☎☏☑☒☜☞☠☪☭☽☾♀♂♝♞♪♭✁✈✌✍✎✐✔✖✘✙✚✪✲❀❂❈❉❤❦❧〄〠㈜㈱㉿㊙㊚㊛㊣㊤㊥㊦㊧㊨囍]){1}/u",$str,$arrCh);
                    $currentCNs = count($arrCh[0]);              //本轮截取到的中文字符个数
                }else{
                    //如果是gbk编码
                    @preg_match_all("/([x80-xff{}¥¨±·×÷ˇˉ‐—―‖‘’“”…ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ∈∏∑√∝∞∠∥∧∨∩∪∫∮∴∵∶∷∽≈≌≠≡≤≥≮≯⊙⊥⌒①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛❶❷❸❹❺❻❼❽❾❿、。〃々〈〉《》「」『』【】〔〕〖〗〝〞㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩︰︴︵︶︷︸︹︺︻︼︽︾︿﹀﹁﹂﹃﹄﹉﹊﹋﹌﹍﹎﹏﹑﹔﹕﹖﹙﹚﹛﹜﹟﹠﹡﹢﹣﹤﹦﹨﹩﹪﹫!"'()+,-/:;<=>?[]_`|~ ̄§×ΘΨ‖‥…№℡←↑→↓↖↗↘↙√∮⊕⊙⊿╱╲▁▂▃▄▅▆▇█▏▔▕■□▲△▼▽◆◇○◎●◢◣◤◥☀☂☃★☆☉☋☍☎☏☑☒☜☞☠☪☭☽☾♀♂♝♞♪♭✁✈✌✍✎✐✔✖✘✙✚✪✲❀❂❈❉❤❦❧〄〠㈜㈱㉿㊙㊚㊛㊣㊤㊥㊦㊧㊨囍]){1}/",$str,$arrCh);
                    $currentCNs = floor(count($arrCh[0])/2);     //本轮截取到的中文字符个数(注:gbk有别于utf-8)
                }            
                $chrSpace = $len - $currentCNs;                  //本轮截取包含非中文字符个数(非中文字符占位数)
                $currentSpaces = $currentCNs * 2 + $chrSpace;    //本轮截取后得到总占位数                
                $diffSpace = $spaceLen - $currentSpaces;         //仍缺少的占位数            
                if($ifEllipsis==true){
                    $dot4space = array(2=>'..',3=>'...');
                    $str .= $dot4space[$diffSpace];              //连接 点点点
                    if($diffSpace<=3){break 1;}
                }else{
                    if($diffSpace<=1){break 1;}
                }
            }
            return $str;
        }
    }
    
    //使用举例
    $Str='本function适用于对1文章2帖子-等‐《标题}按指定长度展示。比如我的展示行最多容得相当于25个汉字长的位置。';
    $getStr = mbSubstrMixStr($Str,$cnNum=25);
    
    echo '<meta http-equiv="content-type" content="text/html; charset=utf-8" />';
    echo '原文展示:',$Str.'<br /><br />';
    echo '参考刻度:国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国<br />';
    echo '截取效果:',$getStr;
    
    ?>
  • 相关阅读:
    C语言归并排序
    三重for循环实现对二维数组的按列排序(JavaScript)
    MySQL创建子视图并查看的时候,字符集报错问题
    Windows下配置lua环境
    《机器学习》周志华西瓜书读书笔记
    《消费金融真经》读书笔记
    北海之行-小纪
    2017中国资产管理行业发展报告——思维导图
    工作小纪
    全球化3.0:世界是红的 (转载)
  • 原文地址:https://www.cnblogs.com/martinzhang/p/3280301.html
Copyright © 2011-2022 走看看