Perl Unicode轉換概括:
1.判斷輸入源的編碼方式
2.輸入源是utf8編碼
a. Encode::_utf8_on($str);開啟utf8 flag。
輸入源非utf8編碼
a. $string = decode(ENCODING,$octets [,CHECK]);將輸入源轉化成utf8編碼並開啟utf8 flag
3.輸出
$str = Encode::encode(ENCODING, $str);把字串從utf8編碼轉成指定的編碼, 並關閉utf8 flag
----------------------------------------------以下內容摘自網路------------------------------------------------------------------------------
Perl Internal Form
Perl中字串只有兩種形式:一種是字串(Perl strings)。另外一種是位元組流(bytes,標準稱作octets)。編碼類別型分別是:utf8編碼(字串)和Ascii(位元組流)
UTF8 FLAG
perl如何確定一個字串是octets還是utf8編碼的字串呢? perl完全是靠字串上的utf8 flag。在perl內部, 字串結構由兩部分組成: 資料和utf8 flag
比如字串“中國”在perl內部的儲存是這樣:
utf8 flag 資料
On 中國
如果utf8 flag是On的話, perl則把“中國”當成utf8字串來處理, 如果utf8 flag為Off, perl就會把他當成octets來處理。但要注意的是:不能根據utf8 flag來判定字串是否是utf8編碼。
樣本1:
use Encode;
use strict;
my $str = "中國";
Encode::_utf8_on($str);
print length($str) . "\n";
Encode::_utf8_off($str);
print length($str) . "\n";
運行結果是:
Malformed UTF-8 character (unexpected end of string) at unicode.pl line 30
2
6
使用Encode模組的_utf8_on函數和_utf8_off函數來開關字串“中國”的utf8 flag。可以看到, utf8 flag開啟的時候,"中國"被當成utf8字串處理, 其長度是2。 utf8 flag關閉的時候,“中國”被當成octets(位元組數組)處理, 出來的長度是6(我的編輯器用的是utf8編碼, 如果你的編輯器用的是gb2312編碼, 那麼長度應該是4)。由於"中國"本來的編碼是gb2312的, 不是utf8的,但開啟utf8 flag後,Perl把"中國"當成utf8處理,這就可能導致錯誤發生:Malformed UTF-8 character(unexpected end of string)
字串來源
為了應用上面說到的基本原則, 我們首先要知道字串本來的編碼和utf8 flag開關情況, 這裡我們討論幾種情況。
1) 命令列參數和標準輸入。 從命令列參數或標準輸入(STDIN)來的字串, 它的編碼跟locale有關。如果你的locale是zh_CN或zh_CN.gb2312,那麼進來的字串就是gb2312編碼, 如果你的locale是zh_CN.gbk, 那麼進來的編碼就是gbk, 如果你的編碼是zh_CN.UTF8, 那進來的編碼就是utf8。不管是什麼編碼, 進來的字串的utf8 flag都是關閉的狀態。
2) 你的原始碼裡的字串。 這要看你編寫原始碼時用的是什麼編碼。 在editplus裡, 你可以通過“檔案”->“另存新檔”查看和更改編碼。在linux下, 你可以cat一個原始碼檔案, 如果中文正常顯示, 說明原始碼的編碼跟locale是一致的。原始碼裡的字串的utf8 flag同樣是關閉的狀態。
如果你的原始碼裡含有中文, 那麼你最好遵循這個原則: 1) 編寫代碼時使用utf8編碼,2)在檔案的開頭加上“use utf8;”語句。這樣, 你原始碼裡的字串就都會是utf8編碼的, 並且utf8 flag也已經開啟。
3) 從檔案讀入。 這個毫無疑問, 你的檔案是什麼編碼, 讀進來就是什麼編碼了。讀進來以後, utf8 flag是off狀態。
小結:不經過特殊處理,字串的utf8 flag是off狀態,perl就會把字串當成octets來對待。這時候, 我們使用$string = decode(ENCODING, $octets) 用來解碼位元組流的。它按照你給出的編碼格式(ENCODING)解釋給定的位元組流,把位元組流從ENCODING編碼轉成utf8編碼,並開啟utf8 flag。不過有個例外就是, 如果字串是僅僅ascii編碼或EBCDIC編碼的話, 不開啟utf8 flag。註:本人尚不清楚如何判定字串是否是ascii編碼或EBCDIC編碼
輸出
字串在程式內被正確地處理後, 要展現給使用者。這時我們需要把字串從perl internal form轉化成使用者能接受的形式。簡單地說, 就是把字串從utf8編碼轉換成輸出的編碼或表現介面的編碼。這時候, 我們使用$str = Encode::encode('charset', $str);把字串從utf8編碼轉成指定的編碼, 並關閉utf8 flag。
同樣可以分為幾種情況:
1) 標準輸出。標準輸出的編碼跟locale一致。輸出的時候utf8 flag應該關閉, 不然就會出現我們前面看到的那行警告:
Wide character in print at unicode.pl line 10.
2)。。。。