utf8 - Perl pragma 用於啟用/停用原始碼中的 UTF-8 (或 UTF-EBCDIC)
use utf8;
no utf8;
# Convert the internal representation of a Perl scalar to/from UTF-8.
$num_octets = utf8::upgrade($string);
$success = utf8::downgrade($string[, $fail_ok]);
# Change each character of a Perl scalar to/from a series of
# characters that represent the UTF-8 bytes of each original character.
utf8::encode($string); # "\x{100}" becomes "\xc4\x80"
utf8::decode($string); # "\xc4\x80" becomes "\x{100}"
# Convert a code point from the platform native character set to
# Unicode, and vice-versa.
$unicode = utf8::native_to_unicode(ord('A')); # returns 65 on both
# ASCII and EBCDIC
# platforms
$native = utf8::unicode_to_native(65); # returns 65 on ASCII
# platforms; 193 on
# EBCDIC
$flag = utf8::is_utf8($string); # since Perl 5.8.1
$flag = utf8::valid($string);
use utf8
pragma 告訴 Perl 剖析器允許程式碼文字中使用 UTF-8,範圍為目前的詞彙範圍。no utf8
pragma 告訴 Perl 切換回將原始碼文字視為目前的詞彙範圍中的字元組。 (在 EBCDIC 平台上,技術上允許的是 UTF-EBCDIC,而不是 UTF-8,但這個區別是學術上的,因此在本文檔中,術語 UTF-8 用於表示兩者)。
不要將此 pragma 用於告訴 Perl 您的腳本是用 UTF-8 編寫的以外的任何用途。下面描述的工具函數可以直接使用,而不需要 use utf8;
。
由於無法可靠地將 UTF-8 與原生 8 位元編碼區分開來,因此您需要在原始碼開頭放置位元組順序標記,或使用 use utf8;
來指示 perl。
當 UTF-8 成為標準原始碼格式時,此 pragma 將實際上變成無操作。
另請參閱 -C
參數及其表親 PERL_UNICODE
環境變數在 perlrun 中的效果。
啟用 utf8
pragma 會產生以下效果
原始文字中不在 ASCII 字元集的位元組將被視為文字 UTF-8 序列的一部分。這包含大部分的文字,例如識別名稱、字串常數和常數正規表示式模式。
請注意,如果您的腳本中有非 ASCII、非 UTF-8 位元組(例如字串文字中的嵌入式 Latin-1),use utf8
將會不滿意。如果您想要在 use utf8
下有這種位元組,您可以停用此 pragma 直到區塊結束(或檔案,如果在頂層)為止,方法是 no utf8;
。
下列函式是由 Perl 核心定義在 utf8::
套件中。您不需要說 use utf8
來使用這些函式,事實上您不應該這樣說,除非您真的想要有 UTF-8 原始碼。
$num_octets = utf8::upgrade($string)
(自 Perl v5.8.0 起)就地將字串的內部表示法從原生編碼(Latin-1 或 EBCDIC)中的八位元組序列轉換為 UTF-8。邏輯字元序列本身不變。如果 $string 已升級,則這是一個空操作。傳回表示字串為 UTF-8 所需的八位元組數目。自 Perl v5.38 起,如果 $string
為 undef
則不採取任何動作;在此之前,它會被轉換為已定義且長度為零。
如果您的程式碼需要與沒有 use feature 'unicode_strings';
的 perl 版本相容,您可以對特定字串強制執行 Unicode 語意
# force unicode semantics for $string without the
# "unicode_strings" feature
utf8::upgrade($string);
例如
# without explicit or implicit use feature 'unicode_strings'
my $x = "\xDF"; # LATIN SMALL LETTER SHARP S
$x =~ /ss/i; # won't match
my $y = uc($x); # won't convert
utf8::upgrade($x);
$x =~ /ss/i; # matches
my $z = uc($x); # converts to "SS"
請注意,此函式不處理任意編碼;請改用 Encode。
$success = utf8::downgrade($string[, $fail_ok])
(自 Perl v5.8.0 起)就地將字串的內部表示法從 UTF-8 轉換為原生編碼(Latin-1 或 EBCDIC)中的等效八位元組序列。邏輯字元序列本身不變。如果 $string 已儲存為原生 8 位元,則這是一個空操作。可用於確保 UTF-8 標記已關閉,例如當您想要確保 substr() 或 length() 函式使用通常較快的位元組演算法時。
如果原始 UTF-8 順序無法在原生 8 位元編碼中表示,則會失敗。失敗時會終止,或是在 $fail_ok 的值為 true 時,傳回 false。
成功時傳回 true。
如果您的程式碼預期會收到八進位元組序列,可以使用此函數驗證是否已收到。
# throw an exception if not representable as octets
utf8::downgrade($string)
# or do your own error handling
utf8::downgrade($string, 1) or die "string must be octets";
請注意,此函式不處理任意編碼;請改用 Encode。
utf8::encode($string)
(自 Perl v5.8.0 起)就地將字元序列轉換成 Perl 延伸 UTF-8 中對應的八進位元組序列。也就是說,每個(可能很寬)的字元都會被一或多個字元序列取代,這些字元序列代表字元的個別 UTF-8 位元組。UTF8 標記會關閉。不傳回任何值。
my $x = "\x{100}"; # $x contains one character, with ord 0x100
utf8::encode($x); # $x contains two characters, with ords (on
# ASCII platforms) 0xc4 and 0x80. On EBCDIC
# 1047, this would instead be 0x8C and 0x41.
類似於
use Encode;
$x = Encode::encode("utf8", $x);
請注意,此函式不處理任意編碼;請改用 Encode。
$success = utf8::decode($string)
(自 Perl v5.8.0 起)嘗試就地將以 Perl 延伸 UTF-8 編碼的八進位元組序列轉換成對應的字元序列。也就是說,它會取代字串中每個序數代表有效(延伸)UTF-8 位元組序列的字元序列,並以對應的單一字元取代。只有當來源字串包含多位元組 UTF-8 字元時,才會開啟 UTF-8 標記。如果 $string 作為延伸 UTF-8 無效,則傳回 false;否則傳回 true。
my $x = "\xc4\x80"; # $x contains two characters, with ords
# 0xc4 and 0x80
utf8::decode($x); # On ASCII platforms, $x contains one char,
# with ord 0x100. Since these bytes aren't
# legal UTF-EBCDIC, on EBCDIC platforms, $x is
# unchanged and the function returns FALSE.
my $y = "\xc3\x83\xc2\xab"; This has been encoded twice; this
# example is only for ASCII platforms
utf8::decode($y); # Converts $y to \xc3\xab, returns TRUE;
utf8::decode($y); # Further converts to \xeb, returns TRUE;
utf8::decode($y); # Returns FALSE, leaves $y unchanged
請注意,此函式不處理任意編碼;請改用 Encode。
$unicode = utf8::native_to_unicode($code_point)
(自 Perl v5.8.0 起)這會取得一個無符號整數(代表程式執行所在平台上字元(或碼點)的序數),並傳回其對應的 Unicode 等效值。由於 ASCII 平台原生使用 Unicode 碼點,因此此函數會在這些平台上傳回其輸入。在 EBCDIC 平台上,它會從 EBCDIC 轉換成 Unicode。
如果輸入不是無符號整數,目前會傳回一個無意義的值。
自 Perl v5.22.0 起,此函數的呼叫會在 ASCII 平台上最佳化,因此在該平台上使用此函數不會影響效能。
$native = utf8::unicode_to_native($code_point)
(自 Perl v5.8.0 起)這是 utf8::native_to_unicode()
的反函數,進行相反方向的轉換。同樣地,在 ASCII 平台上,此函數會傳回其輸入,但在 EBCDIC 平台上,它會找出原生平台碼點,並給定任何 Unicode 碼點。
如果輸入不是無符號整數,目前會傳回一個無意義的值。
自 Perl v5.22.0 起,此函數的呼叫會在 ASCII 平台上最佳化,因此在該平台上使用此函數不會影響效能。
$flag = utf8::is_utf8($string)
(自 Perl 5.8.1 起)測試 $string 是否在內部標示為 UTF-8 編碼。功能上與 Encode::is_utf8($string)
相同。
通常只在除錯和測試時需要,如果你需要傾印 SV 的內部,Devel::Peek 的 Dump() 提供更詳細的資訊,而且格式精簡。
如果你仍然認為在除錯、測試或處理檔名之外需要這個功能,你應該閱讀 perlunitut 和 "perlunifaq 中的「UTF8 標記是什麼?」。
不要使用這個標記來區分字元和二進位資料:這應該在你撰寫程式碼時為每個變數決定。
若要強制在可移植到 perl 5.8 和 5.10 的程式碼中使用 unicode 語意,請無條件呼叫 utf8::upgrade($string)
。
$flag = utf8::valid($string)
(內部)測試 $string 是否在 UTF-8 方面處於一致狀態。如果它是格式良好的 Perl 延伸 UTF-8 且具有 UTF-8 標記,或如果 $string 以位元組形式儲存(這兩種狀態都是「一致」的),則會傳回 true。此常式的用意主要是允許 Perl 的測試套件檢查操作是否已將字串保留在一致狀態。
utf8::encode
類似於 utf8::upgrade
,但會清除 UTF8 標記。請參閱 perlunicode,以及 C API 函式 sv_utf8_upgrade
、"sv_utf8_downgrade" in perlapi
、"sv_utf8_encode" in perlapi
和 "sv_utf8_decode" in perlapi
,它們由 Perl 函式 utf8::upgrade
、utf8::downgrade
、utf8::encode
和 utf8::decode
封裝。此外,函式 utf8::is_utf8
、utf8::valid
、utf8::encode
、utf8::decode
、utf8::upgrade
和 utf8::downgrade
實際上是內部的,因此總是可用,而不需要 require utf8
陳述式。
某些檔案系統可能不支援 UTF-8 檔名,或者它們可能與 Perl 不相容地支援。因此,檔案系統可見的 UTF-8 名稱(例如模組名稱)可能無法運作。