• 按指定长度截取中英文混合字符串


    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;
    
    ?>
  • 相关阅读:
    趁热讲讲skin.xml支持的标签和attributes
    如何配置和编译ogre 1.7.0 + cegui 0.7.1
    关于OGRE基础教程6中CEGUI的layout文件can not locate的问题
    skin.xml皮肤配置讲解
    OCX控件注册相关(检查是否注册,注册,反注册)
    重回博客园继续我的 GUI库
    窗口类的定义
    UI库需要完成的任务
    屏幕截图代码
    深入C++的默认构造函数1
  • 原文地址:https://www.cnblogs.com/martinzhang/p/3280301.html
Copyright © 2020-2023  润新知