》在 Perl看來, 字符串只有兩種形式. 一種是octets, 即8位序列, 也就是咱們一般說的字節數組. 另外一種utf8編碼的字符串, perl管它叫string. 也就是說: Perl只熟悉兩種編碼: Ascii(octets)和utf8(string).php
perl內部字符串由flag標誌位和數據區兩部分組成,其存儲結構以下:css
全部字符串相關的函數包括正則表達式、文件檢測、都會受utf8 flag的影響。在默認狀況下,utf8 flag標誌位是off狀態,當咱們在代碼中使用了 use utf8 ,則表明flag標誌位是on狀態,在當前詞法範圍內都是有效的。html
Encode中的is_utf8函數能夠用於檢測當前flag開啓狀況,1表明on 0表明off;如下代碼均是使用notepad++進行編碼,字符編碼格式選擇UTF-8格式。linux
若要進行不一樣編碼之間的轉換,可使用Encode模塊中的decode函數和encode函數,這兩個函數使用以下正則表達式
$octets = encode(ENCODING, STRING);
將標量字符串STRING從perl內部格式編碼成ENCODING格式,而且返回字節流序列。數組
For example, to convert a string from Perl's internal format into ISO-8859-1:
$octets = encode("iso-8859-1", $string);
$string = decode(ENCODING, OCTETS);
以ENCODING編碼格式從字節流中解讀字符信息,並轉化爲perl內部格式編碼。 markdown
For example, to convert ISO-8859-1 data into a string in Perl's internal format:
$string = decode("iso-8859-1", $octets);
下面展現gbk和utf8之間的相互轉碼,兩種編碼格式須要通過perl內部編碼格式:less
若待編碼的字符串已是perl內部編碼格式(flag on +utf8編碼),則能夠直接進行編碼或者解碼,不須要按照上述的過程進行。函數
例子1:測試
use Encode;
#當前關閉
print "utf8 flag is 0ff\n" if !Encode::is_utf8($string1);
my $string1 = "你好";//是utf8格式,若不編碼屏幕輸出亂碼
print Encode::encode("gbk",Encode::decode("utf8",$string1)),"\n";
#flag是off狀態,看成字節來處理,長度爲6
print "length:",length($string1),"\n";
運行結果:
例子2:
print "***********utf8 flag is on***************\n";
#此後utf8 flag 爲on
use utf8;
my $string2 = "你好";
#當前on
print "utf8 flag is on\n" if Encode::is_utf8($string2);
#這裏$string2至關因而內部格式了 flag is on and utf8 format
#能夠直接編碼,不用先解碼後編碼了
print Encode::encode("gbk",$string2),"\n";
#看成string來處理,長度爲2
print "length:",length($string2),"\n\n\n\n";
運行結果:
咱們在使用perl中的文件測試符-e -s -f或者系統命令copy函數時,均要求這些函數的入參或者變量是gbk編碼格式,不然會致使不符合預期的編碼結果,舉例以下:
我在目錄下這個路徑下建立了txt文件「E:\perl\文件夾1\log.txt」,不一樣的編碼格式答案是不符合預期的。
例子3:
print "**********file test and system copy attentions**************\n";
#文件測試或者調用系統copy函數等函數時 均須要使用gbk編碼
my $src1 = "E:\\perl\\文件夾1\\log.txt";
my $src2 = "E:\\perl\\文件夾1\\log.txt";
#$src2字符串flag標誌位是on,而且自己是utf8編碼,
#所以$src2是perl內部格式,能夠轉爲國標
my $gbk_src = Encode::encode("gbk", $src2);
print "gbk encode:$gbk_src\n";
#文件存在 則打印
if (-e $gbk_src){
print "it exists\n";
}
#文件不存在 則打印
unless (-e $src){
print "it don't exist\n";
}
運行結果:
字符串來源
爲了可以正確的進行字符串編解碼, 咱們首先要知道字符串原本的編碼和utf8 flag開關狀況, 這裏咱們討論幾種狀況.
字符轉碼API
#接口API
sub convert_utf8_to_gbk{
my ($utf8) = @_;
my $gbk = "";
if (Encode::is_utf8($utf8)){
$gbk = Encode::encode('gbk',$utf8);
}
else{
$gbk = Encode::encode('gbk',Encode::decode('utf8',$utf8));
}
return $gbk;
}
sub convert_gbk_to_utf8{
my ($gbk) = @_;
my $utf8 = "";
$utf8 = Encode::decode('gbk',$gbk);
return $utf8;
}
#測試用例
print convert_utf8_to_gbk("你好 中國!!\n"),"\n";
print "input:";
chomp( my $input = <STDIN>);
print "output:",convert_utf8_to_gbk(convert_gbk_to_utf8($input)),"\n";
運行結果:
參考入下資料:
http://blog.csdn.net/c_base_jin/article/details/78768591