perl對中文的支援

2021-09-21 10:17:08 字數 2442 閱讀 6146

大家經常使用正規表示式的字符集從字串中抽取或排除中文字元,但是這樣做很費事,效果也並不是很理想。實際上perl從5.6開始已經開始在內部使用utf8編碼來表示字元,也就是說對中文以及其他語言字元的處理應該是完全沒有問題的。關鍵在於目前使用的編輯器以及檔案格式並不都能很好地支援utf8,委屈了perl的強大能力。

實際上我們只需要利用好encode這個模組便能充分發揮perl的utf8字元的優勢了。

下面就以中文文字的處理為例進行說明(注意:編輯下面這段程式不能用使用utf8編碼的編輯器),比如有乙個字串"測試文字",我們想要把這個中文字串拆成單個

字元,可以這樣寫:

use encode;

use encode::cn; #可寫可不寫

$dat="測試文字";

$str=decode("gb2312",$dat);

@chars=split //,$str;

foreach $char (@chars)

結果大家試一試就知道了,應該是令人滿意的。

這裡主要用到了encode模組的decode、encode函式。要了解這兩個函式的作用,我們需要清楚幾個概念:

1、perl字串是使用utf8編碼的,它由unicode字元組成而不是單個位元組,每個utf8編碼的unicode字元佔1~4個位元組(變長)。

2、進入或離開perl處理環境(比如輸出到螢幕、讀入和儲存檔案等等)時不是直接使用perl字串,而需要把perl字串轉換成位元組流,轉換過程中使用何種編碼方式完全取決於你(或者由perl代勞)。一旦perl字串向位元組流的編碼完成,字元的概念就不存在了,變成了純粹的位元組組合,如何解釋這些組合則是你自己的工作。

我們可以看出如果想要perl按照我們的字元概念來對待文字,文字資料就需要一直用perl字串的形式存放。但是我們平時寫出的每個字元一般都被作為純ascii字元儲存(包括在程式中明文寫出的字串),也就是位元組流的形式,這裡就需要encode和decode函式的幫助了。

encode函式顧名思義是用來編碼perl字串的。它將perl字串中的字元用指定的編碼格式編碼,最終轉化為位元組流的形式,因此和perl處理環境之外的事物打交道經常需要它。其格式很簡單:

$octets = encode(encoding, $string [, check])

這裡$string是perl字串,encoding是給定的編碼方式,$octets則是編碼之後的位元組流,check表示轉換時如何處理畸變字元(也就是perl認不出來的字元)。一般不需要使用check,讓perl按預設規則處理即可。

編碼方式視語言環境的不同有很大變化,預設可以識別utf8、ascii、ascii-ctrl、iso-8859-1等,中文環境(cn)增加了euc-cn(gb2312與之等價)、cp936(gbk與之等價)、hz等,還有日文環境(jp)、韓文(kr)等等,在此不一一盡數。

decode函式則是用來解碼位元組流的。它按照你給出的編碼格式解釋給定的位元組流,將其轉化為使用utf8編碼的perl字串,一般來說從終端或者檔案取得的文字資料都應該用decode轉換為perl字串的形式。它的格式為:

$string = decode(encoding, $octets [, check])

$string、encoding、$octets和check的含義同上。

現在就很容易理解上面寫的那段程式了。因為字串是用明文寫出的,存放的時候已經是位元組流形式,喪失了本來的意義,所以首先就要用decode函式將其轉換為perl字串,由於漢字一般都用gb2312格式編碼,這裡decode也要使用gb2312編碼格式。轉換完成後perl對待字元的行為就和我們一樣了,平時對字串進行操作的函式基本上都能正確對字元進行處理,除了那些本來就把字串當成一堆位元組的函式(如vec、pack、unpack等)。

於是split就能把字串切成單個字元了。最後由於在輸出的時候不能直接使用utf8編碼的字串,還需要將切割後的字元用encode函式編碼為gb2312格式的位元組流,再用print輸出。

encode模組的初步應用大概就是這樣,詳細情況還是要參閱模組的文件。實際上如果我們使用ultraeditor等等支援編輯utf8編碼檔案的編輯器寫程式,基本上用不著encode模組,在程式開頭加上一句use utf8就行。這時perl預設包括程式本身在內的所有的字元都是unicode字元,可以隨便使用unicode範圍內的字元,甚至可以用非英文本元作為識別符號,只是輸出的時候可能還需要用encode模組。比如用ue的utf8編碼模式編輯這個程式:

use utf8;

$單價=10;

$數量=100;

$總額=$單價*$數量;

print "$總額\n";

可以在perl 5.6以後的版本中正常執行並給出結果,是不是很爽?:) 這種模式最大的優點就是在字串中可以混合多種語言的文字,就算中日韓英加上阿拉伯字元都在乙個字串**現也沒問題;不像使用encode模組那樣必須固定一種編碼方式,中日韓英字元同時出現還好辦,因為gbk包含了所有這些字元,可是再加上一些非亞洲語言字元就不一定能處理了。所以以後用unicode編碼應該是大勢所趨。

Perl對中文的處理 encode,decode

perl對中文的處理 encode,decode 最近在處理中文時遇到亂碼的問題,google了一下,發現下面這篇文章。茅塞頓開!perl從5.6開始已經開始在內部使用utf8編碼來表示字元,也就是說對中文以及其他語言字元的處理應該是完全沒有問題的。我們只需要利用好encode這個模組便能充分發揮p...

perl對中文的處理 encode,decode

最近在處理中文時遇到亂碼的問題,google了一下,發現下面這篇文章。茅塞頓開!perl從5.6開始已經開始在內部使用utf8編碼來表示字元,也就是說對中文以及其他語言字元的處理應該是完全沒有問題的。我們只需要利用好encode這個模組便能充分發揮perl的utf8字元的優勢了。下面就以中文文字的處...

perl對中文的處理 encode,decode

最近在處理中文時遇到亂碼的問題,google了一下,發現下面這篇文章。茅塞頓開!perl從5.6開始已經開始在內部使用utf8編碼來表示字元,也就是說對中文以及其他語言字元的處理應該是完全沒有問題的。我們只需要利用好encode這個模組便能充分發揮perl的utf8字元的優勢了。下面就以中文文字的處...