中文字符串截取處理一直是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 合法性。
<?php //使用 preg_match_all 匹配所有多字節字符。將結果保存到$result數組中 preg_match_all('/./us', $str, $result); ?>
接著只需要使用 array_slice 函數取出字符串數組中響應數值就可以了,全部代碼如下:
<?php 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中的一段代碼,很好地解決了這個問題
<?php 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函數進行一下簡單的轉換。
函數原型如下:
<?php string iconv ( string $in_charset , string $out_charset , string $str ); ?>
window下可以使用一個叫“超級批量編碼轉換 1.0” 的軟件進行字符編碼的批量轉換工作。