14.12. Perl 中文程式設計

如何排除 Perl 程式處理中文資料的障礙?

在 CGI Perl 程式中,有許多符號字元是有特殊用途的, 而不幸的有某些這樣的字元卻與中文字的第二個位元組互相衝突, 以至於會有中文字顯示或比對不正確,甚至是產生錯誤結果的現象, 尤其是 | 及 \ 這兩個字元,所幸我們還有個 quotemeta 指令可以使用, 這個指令可以將指定的字串中每個字元的前面都再多加上一個 \ 這個字元,使得字串內的特殊字元在處理時被視為單純的字碼, 請參考下列的範例:

假設 $str 是一個要做搜尋比對的中文字串,而 $line 是逐行讀入的資料檔內容:

$restr = quotemeta $str;
if ($line !~ m/$restr/i) { ......
}

另外若不是以變數來處理的字串,通常我們會使用雙引號來標示及處理, 然而這也是會發生上述的障礙,但是當您直接對雙引號括住的字串使用 quotemeta 來處理時卻又會怪怪的,那怎麼辦呢?很間單! 將雙引號改為單引號就可以囉∼因為單引號不會對其內的字元作特殊處理, 換句話講在單引號之內的文字資料將會原原本本的呈現出來, 不會去解譯變數也不會處理 escape 字元 ,例如原來的敘述是:

print "測試成功的$msg訊息!\n";

應改為:

print '測試成功的訊息!';

請特別注意 \n 換行符號及 $msg 變數也需拿掉,因為單引號並不處理 escape 字元及變數,如果不將 \n 符號及 $msg 變數拿掉, 那麼顯示出來的字樣將會是

成功的$msg訊息!\n

,如果您仍希望顯示成原來包含變數及換行的效果, 那就必須將單引號與雙引號資料併用,同時以 . 符號來連結成完整的輸出敘述:

print '成功的'.$msg.'訊息!'."\n";

上述結論就是當印出 成功的 與 訊息! 字樣是使用單引號, 而換行的 \n 則是用雙引號。

以下是一個將檔案中所有的中文字移除的程式範例:

#!/usr/bin/perl -w
# ./bg5rm.pl filename
# and it's will generate a filename.bg5rm
$ifname=$ARGV[0];
open(IF,"$ifname");
open(OF,">${ifname}.bg5rm");
$big5 = "[\xA1-\xF9][\x40-\x7E\xA1-\xFE]";
while(<IF>) {
  s/$big5//g;
  print OF $_;
  print $_;
}
close(IF);
close(OF);

以下是一個將文章中的中英文 word split 進 list:

my $big5 = q{
    [\xA1-\xF9][\x40-\x7E\xA1-\xFE]
};
my $big5plus = q{
    [\x81-\xFE][\x40-\x7E\x80-\xFE]
};
my @chars = /$big5|$ascii+/gox;
my @charsplus = /$big5plus|$ascii+/gox;

MPX 的 解決 Perl 處理中文字的問題

CJKV Information Processing 這本書有些不錯的 perl 程式 範例,其中 *.pdf 是一些討論 perl 下處理 multibyte 的 papers。

Erik Peterson 寫了一些有用的 Perl 程式, 可處理中文轉換。

WWW: http://www.perl.org/