按指定长度截取中英文混合字符串
PHP对中文字符串的指定长度截取一直都是个痛,原因是中文是多字节的,容易截出乱码。对中文英文混合字符串指定长度截取更是不好解决,但只要认真分析还是可以解决的。看本函数:
<?php /** * 功能:按指定长度截取中英文混合字符串 * @param $string 必选 待截取的字符串 * @param $cnNum 必选 需要截取相当于cnNum个汉字个数的长度 * @param $ifEllipsis 可选 返回的字符串末尾是否需要 .. 点点连接:true是(默认);false否; * @param $start 可选 起始截取位置,从第几个字符开始截取(默认0,一个汉字是一个字符) * @return 返回截取后的新字符串 * @author martinzhang */ function mbSubstrMixStr($string, $cnNum, $ifEllipsis = true, $start = 0) { $retrunStr = ''; $ifEllipsis = $ifEllipsis === true ? true : false; $start = $start == '' ? 0 : $start; //需占截取出的占位个数(注:每个英文字符为1个占位,每个汉字为2个占位) $spaceLen = $cnNum * 2; if (strlen($string) <= $cnNum * 3) { return $string; } else { for ($i = -1; $i <= $spaceLen; $i++) { $len = $cnNum + $i; //本轮需要截取字符个数 $retrunStr = mb_substr($string, $start, $len); preg_match_all("/([\x{4e00}-\x{9fa5}{}¥¨±·×÷ˇˉ‐—―‖‘’“”…ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ∈∏∑√∝∞∠∥∧∨∩∪∫∮∴∵∶∷∽≈≌≠≡≤≥≮≯⊙⊥⌒①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒐⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛❶❷❸❹❺❻❼❽❾❿、。〃々〈〉《》「」『』【】〔〕〖〗〝〞㈠㈡㈢㈣㈤㈥㈦㈧㈨㈩︰︴︵︶︷︸︹︺︻︼︽︾︿﹀﹁﹂﹃﹄﹉﹊﹋﹌﹍﹎﹏﹑﹔﹕﹖﹙﹚﹛﹜﹟﹠﹡﹢﹣﹤﹦﹨﹩﹪﹫!"'()+,-/:;<=>?[]_`|~ ̄§×ΘΨ‖‥…№℡←↑→↓↖↗↘↙√∮⊕⊙⊿╱╲▁▂▃▄▅▆▇█▏▔▕■□▲△▼▽◆◇○◎●◢◣◤◥☀☂☃★☆☉☋☍☎☏☑☒☜☞☠☪☭☽☾♀♂♝♞♪♭✁✈✌✍✎✐✔✖✘✙✚✪✲❀❂❈❉❤❦❧〄〠㈜㈱㉿㊙㊚㊛㊣㊤㊥㊦㊧㊨囍]){1}/u", $retrunStr, $arrCh); $currentCNs = count($arrCh[0]); //本轮截取到的中文字符个数 $chrSpace = $len - $currentCNs; //本轮截取包含非中文字符个数(非中文字符占位数) $currentSpaces = $currentCNs * 2 + $chrSpace; //本轮截取后得到总占位数 $diffSpace = $spaceLen - $currentSpaces; //仍缺少的占位数 $dot4space = [2 => '..', 3 => '...']; if ($ifEllipsis == true && isset($dot4space[$diffSpace])) { $retrunStr .= $dot4space[$diffSpace]; //连接 点点点 if ($diffSpace <= 3) { break 1; } } else { if ($diffSpace <= 1) { break 1; } } } return $retrunStr; } } //使用举例//////////////////////////////////////////////////////////////////////////////////////////// $Str = '本function适12eft囍Ⅱ于对①文章帖子-等‐《标题}按指定长度展示。比如我的展示行最多容得相当于25个汉字长的位置。'; $getStr = mbSubstrMixStr($Str, $cnNum = 15); echo '<meta http-equiv="content-type" content="text/html; charset=utf-8" />'; echo '原文展示:', $Str . '<br /><br />'; echo '参考刻度:国国国国国国国国国国国国国国国国国国国国国国国国国国国国国国<br />'; echo '截取效果:', $getStr;