如果一個中文字串,想要逐字拆解。直接用split會得到一堆亂七八糟的東西..
$ln="精讚中文字字串"; @wds= split //, $ln; print "@wds"; #印出拆出來的東西 print $#wds; # 陣列最後一個的索引 20
結果是一堆顯示不出來的亂碼
??????????????
而陣列的大小就是最後一個項目的索引+1,也就是21。
換句話說,一個中文字大小是3Bytes,split函數把他徹底的分開了。
上網找到[1]給我靈感,他的說法是這串你看起來是中文字串的中文字串,其實在PERL裡面是一個個character組成的,直接把他拆了就會變成你看不懂的一些亂碼,你得先把他用 utf8的編碼給解開。
什麼?我一直認為是要組合?所以邏輯上我還是沒有搞懂,不過這樣子修改就能得到正確的結果:
use Encode; $ln="精讚中文字字串"; $ln=decode('utf8',$ln); @wds= split //, $ln; print "@wds"; #精 讚 中 文 字 字 串 print $#wds; # 6
總之這樣是正確的運作了。
第1行 引入 Encode 函式庫
第3行 將原字串用 utf8的方式來解開
其餘不變,輸出的結果第5行會跳警告(不要警告的話此文後面有解法)
Wide character in print at 01.pl line 5.
但第5行的確就能一個字一個字限開的放到陣列中。
陣列最後一個的索引 6代表陣列大小是7。
但是…我還是真的想知道PERL到底是怎麼處理中文字的?在[5]的文章解釋非常的清楚。
UTF8 TAG?
原來中文字串中的中文字是否要獨立看待是靠一個utf8的tag來作判斷,這個tag可使用 _utf8_on/ _utf8_off 來開關。
use Encode; my $str = "中國字" ; Encode::_utf8_on( $str ); print length ( $str ) . "\n" ; #3 Encode::_utf8_off( $str ); print length ( $str ) . "\n" ; #9
第3~4行 把tag打開的話,字串長度就變成3
第5~6行 把tag關閉的話,字串長度就變成9
拆解中文字串的檔案
use Encode; open(FILE, 'file.txt') or die "$!"; $n=0; while($line= <FILE>){ Encode::_utf8_on( $line ); @wd =split //, $line; print "@wd"; } close(FILE);
這樣就能正確的拆解了。
Wide character in print 錯誤
要解決一直出現的[2] Wide character in print at,你可以這樣子做:
use utf8;
binmode(STDOUT, ':encoding(utf8)');
結論
指定開啟 utf8 tag 來分割和剖析字串
設定輸出為utf8來避免警告。
參考資料
[1] https://blog.csdn.net/guo40/article/details/4037052
[2] https://blog.wu-boy.com/2009/07/perl-with-utf-8-mode/
[3] https://dotblogs.com.tw/jimmyyu/2009/08/18/10113
[4] https://www.csie.ntu.edu.tw/~p92005/Joel/Unicode.html
[5] http://heavenchou.buddhason.org/node/225
[6] https://www.key-shortcut.com/en/writing-systems/%E6%96%87%E5%AD%97-chinese-cjk/cjk-characters-1/