Perl Unicode轉換(大部分摘自網路)

來源:互聯網
上載者:User

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)。。。。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.