轉載本站文章請註明,轉載自:扶凱 [ http://www.php-oa.com ]
本文鏈接: http://www.php-oa.com/2008/12/13/perl-unicode.html
轉自:http://blog.chinaunix.net/u2/70049/showart_1210487.html
耐心看完本文, 相信你今後在unicode處理上不會再有什麼問題.
本文內容適用於perl 5.8及其以上版本.
以Perl 看來, 字符串只有兩種形式. 一種是octets, 即8位序列, 也就是我們通常說的字節數組二進製文件. 另一種utf8編碼的字符串, perl管它叫string. 也就是說: Perl只認識兩種編碼: Ascii(octets)和utf8(string).
utf8 flag
那麼perl如何確定一個字符串是octets 還是utf8編碼的字符串呢? perl可沒有什麼智能, 他完全是靠字符串上的utf8 flag. 在perl內部, 字符串結構由兩部分組成: 數據和utf8 flag (標記). 比如字符串"中國"在perl內部的存儲是這樣:
如果utf8 flag 是On 的話, perl就會把中國當成utf8字符串來處理, 如果utf8 flag 為Off, perl 就會把他當成octets 來處理. 所有字符串相關的函數包括正則表達式都會受utf8 flag 的影響. 讓我們來看個例子:
程序代碼:
use Encode;
use strict;
my $str = "中國" ;
Encode::_utf8_on( $str );
print length ( $str ) . "\n" ;
Encode::_utf8_off( $str );
print length ( $str ) . "\n" ;
運行結果是:
程序代碼:
2
6
這裡我們使用Encode 模塊的_utf8_on 函數和_utf8_off 函數來開關字符串"中國"的utf8 flag. 可以看到, utf8 flag 打開的時候, "中國"被當成utf8字符串處理, 所以其長度是2. utf8 flag 關閉的時候, "中國"被當成octets(字節數組)處理, 出來的長度是6(我的編輯器用的是utf8 編碼, 如果你的編輯器用的是gb2312 編碼, 那麼長度應該是4) .
再來看看正則表達式的例子:
程序代碼:
use Encode;
use strict;
my $a = "china----中國" ;
my $b = "china----中國" ;
Encode::_utf8_on( $a );
Encode::_utf8_off( $b );
$a =~ s/\W+//g;
$b =~ s/\W+//g;
print $a , "\n" ;
print $b , "\n" ;
運行結果:
程序代碼:
Wide character in print at unicode.pl line 10.
china中國
china
結果第一行是一條警告, 這個我們稍後再討論. 結果的第二行說明, utf8 flag 開啟的情況下, 正則表達式中的\w能夠匹配中文, 反之則不能.
如何確定一個字符串的utf8 flag 是否已開啟? 使用Encode::is_utf8($str). 這個函數並不是用來檢測一個字符串是不是utf8 編碼, 而是僅僅看看它的utf8 flag 是否開啟.