发一个刚编的暴力版/温柔版中文截取函数
推荐使用暴力版的, 安全可靠; 温柔版的从程序编写的角度看比较高效. 呵呵
基本原理是修正 off, len 可能的错位, 温柔版是从 off 往前倒寻, 寻到第一个 <0xa0 的字符认为是普通字符, 搜寻结束, 根据次数判定是否有错位...
<?php /** * @brief 简洁高效的字符串截取函数 (支持 CJK字符) * * 只是简单判断了高位部分的ASCII值, 能应付绝大多数正规的中英文混合字符串 * 不支持 4字节或3字节的 utf 编码 * * 要点: 修正双字节中错位的 off 值 / len 值 (注意参数 $len 缺省值为 -1的用意) * 用法和 substr() 一样, 针对 GBK 码的低位(0x40开始)可能有问题 */ function my_substr($str, $off, $len = -1) { $mlen = strlen($str); /* 第0步: 参数安全检查与修正 */ if ($off < 0) $off += $mlen; if ($off > $mlen) $off = 0; /* 第1步: $off 修正, 倒寻 */ if ($off > 0) { $fix = $off; $mb = false; do { $ch = ord($str{$fix--}); if ($ch < 0x80) break; $mb = true; } while ($fix); if ($mb) { $fix = ($off - $fix); if ($fix & 1) { $off--; $len++; } } } /* 第2步: $len 修正, 同上 */ if ($len <= 0 || ($len + $off) >= $mlen) { $len = $mlen - $off; } else { $fix = $off + $len; $mb = false; do { $ch = ord($str{$fix--}); if ($ch < 0x80) break; $mb = true; } while ($fix > $off); if ($mb) { $fix = $fix - $off; if (!($fix & 1)) $len--; } } return substr($str, $off, $len); } /** 超级暴力有效的中文截取函数 */ function my_substr2($str, $off, $len = 0) { $mlen = strlen($str); /* 第1步: 暴力修正 off 值 */ if ($off < 0) $off += $mlen; if ($off > $mlen) $off = 0; for ($i = 0; $i < $off ; $i++) { $ch = ord($str{$i}); if ($ch > 0xa0) $i++; } /* 第1步: 暴力修正 len 值 */ $off = $i; if ($len <= 0 || $len > ($mlen - $off)) $len = ($mlen - $off); $end = $off + $len; while ($i < $end) { $ch = ord($str{$i++}); if ($ch > 0xa0) $i++; } return substr($str, $off, $i - $off); }
永久链接:http://www.phprm.com/function/6341aaaf95ba95ce0736d4107061fed4.html
转载随意!带上文章地址吧。