筆記一下Perl程式要UTF-8化的步驟

1. 啟用UTF-8

於檔案前面增加use utf8;,表示全部字串都會以UTF-8來處理,而若不指定時,本身字串必須被設定成UTF-8的TAG才可正常運作,如Encode::_utf8_on( $str );

2. UTF-8解碼與編碼

主要問題為讀入UTF-8編碼的檔案,進行substr時中文的部分會被切壞,或者使用length取得字串長度,會被當成ASCII來處理,故讀取時需解碼,寫入時須先編碼。但如開啟檔案有指定編碼,則不自行解編碼。

  1. 於檔案開頭引入以下: use Encode qw(decode_utf8 encode_utf8);
  • 讀取的結果須進行解碼,例如:decode_utf8($str)
  • 寫入前必須先進行編碼,例如:encode_utf8($str)
  1. 開啟檔案時可指定編碼,例如:open( DATA, "<:encoding(UTF-8)", "file.txt" )

3. 輸出指定為UTF-8

主要問題為,輸出UTF-8編碼時會出現Wide character in print at的錯誤,必須指定輸出編碼。

use utf8;
binmode(STDOUT, ':encoding(utf8)');

範例

如以一個UTF-8編碼的.pl檔案來說,裡面可為UTF-8字串,且可以讀取UTF-8編碼的檔案,並將上述內容印出。

#!/usr/bin/perl

use strict;
use warnings;
# 啟用UTF-8
use utf8;
use Encode qw(decode_utf8 encode_utf8);
# 輸出指定為UTF-8
binmode( STDOUT, ':encoding(utf8)' );

my $test = "這是中文\n";
print $test;

my @tmp = ();

print "第一次開檔\n";

# 可在讀檔的時候指定編碼,則不需要再自行將UTF-8解碼
open( DATA, "<:encoding(UTF-8)", "file.txt" )
  || die "Couldn't open file file.txt, $!";

@tmp = <DATA>;

print '印出@tmp' . "\n===\n";
for my $i (@tmp) {
    print $i;
}

# 寫入檔案也指定編碼即可正常運作
print "\n===\n寫入檔案\n";
open( DATA, ">:encoding(UTF-8)", "file.txt" )
  || die "Couldn't open file file.txt, $!";

print DATA @tmp;
close(DATA) || die "Couldn't close file properly";

print "第二次開檔\n";

# 如果讀檔的時候沒指定編碼,則要自行解碼
open( DATA, "<", "file.txt" ) || die "Couldn't open file file.txt, $!";

while (<DATA>) {
    # 使用decode_utf8解碼檔案內容
    print decode_utf8($_);
}
close(DATA) || die "Couldn't close file properly";

參考資料