話說....Big5編碼一直是我們在做字串處理時的痛,因為Big5屬於Double Byte字元而且結尾那個byte的編碼好死不死又跟ASCII Code重複,導致像是許功蓋這些結尾字元在ASCII Code裡面為\(脫逸符號)、\t(tab)、\n(換行)等符號的字元在輸出的時候都會有問題,在我還是大學生的時候,這問題困擾了我好久,因為除了顯示時add_slash不能在這些字串後面多個'\'之外,老闆還叫我開發個文章自動斷行系統,不能截掉英文單字且中文字要能正常顯示,截英文字事小,只要back track回上一個空白字元就好(ASCII Code=32),重點是這個系統的萬年資料庫是Big5編碼的,整個的欲哭無淚,經過三週的奮戰後,我終於解決了這個問題,不過時間久了也忘記要怎麼解了,今天心血來潮上網找了兩種解法,當然最根本的還是捨Big5用UTF-8來存字串最好囉。
第一種是逐一比對每一個Byte,若此Byte>127則表示為中文字(Big5的First Byte > 127),下一個Byte和這個Byte為同一個字組,這個解法是我那時候使用的解法,印象中PHP的版本還是3.x的時候
function subBig5Str($str,$len){
//檢查原本的字串是不是比要截的長度長
if(strlen($str) > $len){
//比較長才開始截字串
for($i=0;$i<$len;$i++){
//每一次拿一個byte來檢查
$first_byte=substr($str,$i,1);
if(ord($first_byte)>127){
//如果$firest_byte大於127表示為Double byte字元
//跳過下一個字元檢查(因為是同一個字)
$i++;
}
}
//最後可以得到裁字的結尾$i
$str=substr($str,0,$i);
}
return $str;
}
第二種則是透過iconv來解決,很漂亮的一行搞定。
iconv_substr($str,0,18,'big5');