中文字符串截取处理一直是phper们的头疼的问题。尽管,我们可以加载mb_*函数,如果你使用是自己的独立服务器的话;尽管,下一代的PHP6原生支持unicode,貌似php6实际生产环境还没有影。太多的尽管,也很头疼,我们只能自己动手写一个简单的函数,满足中文处理的需求。自己动手,丰衣足食嘛^_^!
我们把函数原型定义为:my_substr($str = ”, $offset = 0, $len = 0);
和mb_substr很像吧。
要用到的函数有 strlen、 preg_match_all、implode和array_slice
还记得preg_match_all 中匹配模式中的”u”修正符吗?
此修正符启用了一个 PCRE 中与 Perl 不兼容的额外功能。模式字符串被当成 UTF-8。本修正符在 Unix 下自 PHP 4.1.0 起可用,在 win32 下自 PHP 4.2.3 起可用。自 PHP 4.3.5 起开始检查模式的 UTF-8 合法性。
//使用 preg_match_all 匹配所有多字节字符。将结果保存到$result数组中
preg_match_all('/./us', $str, $result);
?>
接着只需要使用 array_slice 函数取出字符串数组中响应数值就可以了,全部代码如下:
function my_substr($str = '', $offset = 0, $len = 0){
$len || ($len = strlen($str));
preg_match_all('/./us', $str, $result);
return implode('', array_slice($result[0], $offset, $len));
}
?>
需要注意到的是,如果你使用的是PHP版本是4.2.3之前的老版本,可能”u”选项不会起作用;我们需要更复杂一些的代码来做中文字符串截取工作了。Wordpress中的一段代码,很好地解决了这个问题
if (!function_exists('mb_substr')) {
function mb_substr($str, $start, $len = '', $encoding="UTF-8"){
$limit = strlen($str);
for ($s = 0; $start > 0;--$start) {// found the real start
if ($s >= $limit)
break;
if ($str[$s] <= "\x7F")
++$s;
else {
++$s; // skip length
while ($str[$s] >= "\x80" && $str[$s]<= "\xBF")
++$s;
}
}
if ($len == '') return substr($str, $s);
else
for ($e = $s; $len > 0; --$len) {//found the real end
if ($e >= $limit)
break;
if ($str[$e] <= "\x7F")
++$e;
else {
++$e;//skip length
while ($str[$e] >= "\x80" && $str[$e] <= "\xBF" && $e < $limit)
++$e;
}
}
return substr($str, $s, $e - $s);
}
}
?>
可能你已经看出来了,上面的代码都是针对UTF-8编码格式的多字节字符,如果需要使用gbk或gb2312字符集,则需要使用iconv函数进行一下简单的转换。
函数原型如下:
string iconv ( string $in_charset , string $out_charset , string $str );
?>
window下可以使用一个叫“超级批量编码转换 1.0” 的软件进行字符编码的批量转换工作。