檢視原始碼 unicode (stdlib v6.2)
用於轉換 Unicode 字元的函式。
此模組包含在不同字元表示法之間轉換的函式。它可以在 ISO Latin-1 字元和 Unicode 字元之間轉換,但也可以在不同的 Unicode 編碼(例如 UTF-8、UTF-16 和 UTF-32)之間轉換。
Erlang 二進位檔案中的預設 Unicode 編碼是 UTF-8,這也是 OTP 中的內建函式和函式庫預期找到二進位 Unicode 資料的格式。在列表中,Unicode 資料編碼為整數,每個整數代表一個字元,並簡單地編碼為該字元的 Unicode 碼位。
除了代表碼位的整數或二進位檔案中的 UTF-8 之外的其他 Unicode 編碼,稱為「外部編碼」。在二進位檔案和列表中,ISO Latin-1 編碼稱為 latin1 編碼。
建議僅在與需要此編碼的外部實體通信時才使用外部編碼。在 Erlang/OTP 環境中工作時,建議在表示 Unicode 字元時,將二進位檔案保持為 UTF-8。ISO Latin-1 編碼同時支援向後相容性和與不支援 Unicode 字元集的外部實體通信。
程式應始終在正規化的形式上操作,並將標準等效的 Unicode 字元視為相等。因此,所有字元都應在系統邊界上正規化為一種形式。以下函式之一可以將字元轉換為正規化的形式:characters_to_nfc_list/1
、characters_to_nfc_binary/1
、characters_to_nfd_list/1
或 characters_to_nfd_binary/1
。對於一般文字,建議使用 characters_to_nfc_list/1
或 characters_to_nfc_binary/1
,而對於識別碼,出於安全考量,建議使用相容性正規化函式之一,例如 characters_to_nfkc_list/1
。正規化函式在 OTP 20 中引入。有關正規化的其他資訊,請參閱 Unicode 常見問題。
摘要
型別
一個 binary/0
,其中字元以使用者指定的 UTF-8 以外的 Unicode 編碼(即 UTF-16 或 UTF-32)編碼。
一個 binary/0
,其中字元以 ISO Latin-1 編碼。
一個 integer/0
,代表有效的 ISO Latin-1 字元 (0-255)。
一個 binary/0
,其中字元以 UTF-8 編碼標準編碼。
函式
檢查二進位檔案開頭是否有 UTF 位元組順序標記 (BOM)。
行為如同 characters_to_list/2
,但產生二進位檔案而不是 Unicode 列表。
將可能很深的整數和二進位檔案列表轉換為代表 Unicode 字元的整數列表。輸入中的二進位檔案可以將字元編碼為以下其中之一:
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的標準等效複合字元形式。
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的標準等效複合字元形式。
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的標準等效分解字元形式。
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的標準等效分解字元形式。
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的相容等效複合字元形式。
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的相容等效複合字元形式。
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的相容等效分解字元形式。
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的相容等效分解字元形式。
從提供的 InEncoding
建立 UTF 位元組順序標記 (BOM) 作為二進位檔案。
型別
-type chardata() :: charlist() | unicode_binary().
-type charlist() :: maybe_improper_list(char() | unicode_binary() | charlist(), unicode_binary() | []).
-type endian() :: big | little.
-type external_chardata() :: external_charlist() | external_unicode_binary().
-type external_charlist() :: maybe_improper_list(char() | external_unicode_binary() | external_charlist(), external_unicode_binary() | []).
-type external_unicode_binary() :: binary().
一個 binary/0
,其中字元以使用者指定的 UTF-8 以外的 Unicode 編碼(即 UTF-16 或 UTF-32)編碼。
-type latin1_binary() :: binary().
一個 binary/0
,其中字元以 ISO Latin-1 編碼。
-type latin1_char() :: byte().
一個 integer/0
,代表有效的 ISO Latin-1 字元 (0-255)。
-type latin1_chardata() :: latin1_charlist() | latin1_binary().
等同於 iodata/0
。
-type latin1_charlist() :: maybe_improper_list(latin1_char() | latin1_binary() | latin1_charlist(), latin1_binary() | []).
等同於 iolist/0
。
-type unicode_binary() :: binary().
一個 binary/0
,其中字元以 UTF-8 編碼標準編碼。
函式
-spec bom_to_encoding(Bin) -> {Encoding, Length} when Bin :: binary(), Encoding :: latin1 | utf8 | {utf16, endian()} | {utf32, endian()}, Length :: non_neg_integer().
檢查二進位檔案開頭是否有 UTF 位元組順序標記 (BOM)。
如果提供的二進位檔案 Bin
以 UTF-8、UTF-16 或 UTF-32 的有效 BOM 開頭,則該函式會傳回已識別的編碼以及 BOM 長度(以位元組為單位)。
如果找不到 BOM,則該函式會傳回 {latin1,0}
。
-spec characters_to_binary(Data) -> Result when Data :: latin1_chardata() | chardata() | external_chardata(), Result :: binary() | {error, binary(), RestData} | {incomplete, binary(), binary()}, RestData :: latin1_chardata() | chardata() | external_chardata().
-spec characters_to_binary(Data, InEncoding) -> Result when Data :: latin1_chardata() | chardata() | external_chardata(), InEncoding :: encoding(), Result :: binary() | {error, binary(), RestData} | {incomplete, binary(), binary()}, RestData :: latin1_chardata() | chardata() | external_chardata().
-spec characters_to_binary(Data, InEncoding, OutEncoding) -> Result when Data :: latin1_chardata() | chardata() | external_chardata(), InEncoding :: encoding(), OutEncoding :: encoding(), Result :: binary() | {error, binary(), RestData} | {incomplete, binary(), binary()}, RestData :: latin1_chardata() | chardata() | external_chardata().
行為如同 characters_to_list/2
,但產生二進位檔案而不是 Unicode 列表。
InEncoding
定義如果 Data
中存在二進位檔案,則應如何解釋輸入
OutEncoding
定義應以何種格式產生輸出。
選項
unicode
-utf8
的別名,因為這是二進位檔案中 Unicode 字元的偏好編碼。utf16
-{utf16,big}
的別名。utf32
-{utf32,big}
的別名。
原子 big
和 little
表示大端或小端編碼。
錯誤和例外情況與 characters_to_list/2
中的情況相同,但元組 error
或 incomplete
中的第二個元素是 binary/0
,而不是 list/0
。
-spec characters_to_list(Data) -> Result when Data :: latin1_chardata() | chardata() | external_chardata(), Result :: string() | {error, string(), RestData} | {incomplete, string(), binary()}, RestData :: latin1_chardata() | chardata() | external_chardata().
-spec characters_to_list(Data, InEncoding) -> Result when Data :: latin1_chardata() | chardata() | external_chardata(), InEncoding :: encoding(), Result :: string() | {error, string(), RestData} | {incomplete, string(), binary()}, RestData :: latin1_chardata() | chardata() | external_chardata().
將可能很深的整數和二進位檔案列表轉換為代表 Unicode 字元的整數列表。輸入中的二進位檔案可以將字元編碼為以下其中之一:
- ISO Latin-1(0-255,每個位元組一個字元)。在此情況下,大小寫參數
InEncoding
應指定為latin1
。 - 其中一種 UTF 編碼,指定為參數
InEncoding
。
請注意,列表中的整數始終代表碼位,而與傳遞的 InEncoding
無關。如果傳遞 InEncoding latin1
,則僅允許碼位 < 256;否則,允許所有有效的 Unicode 碼位。
如果 InEncoding
為 latin1
,則參數 Data
對應於 iodata/0
型別,但對於 unicode
,參數 Data
可以包含 > 255 的整數(超出 ISO Latin-1 範圍的 Unicode 字元),這會使其作為 iodata/0
無效。
此函式的目的主要是將 Unicode 字元的組合轉換為列表表示形式的純 Unicode 字串,以便進一步處理。為了將資料寫入外部實體,反向函式 characters_to_binary/3
很有用。
選項 unicode
是 utf8
的別名,因為這是二進位檔案中 Unicode 字元的偏好編碼。utf16
是 {utf16,big}
的別名,而 utf32
是 {utf32,big}
的別名。原子 big
和 little
表示大端或小端編碼。
如果無法轉換資料,原因可能是列表中的 Unicode/ISO Latin-1 字元不合法,或是任何二進位檔案中的 UTF 編碼無效,則會傳回錯誤元組。錯誤元組包含標籤 error
、代表錯誤發生之前可以轉換的字元的列表,以及包括錯誤的整數/位元組在內的字元表示。最後一部分主要用於偵錯,因為它仍然構成一個可能很深或混合的列表,或者兩者都有,不一定與原始資料的深度相同。錯誤發生在遍歷列表時,並且將保留任何要解碼的內容「原樣」傳回。
但是,如果輸入 Data
是純二進位檔案,則錯誤元組的第三部分保證也將是二進位檔案。
發生錯誤的原因如下:
超出範圍的整數。
如果
InEncoding
為latin1
,則每當在列表中找到 > 255 的整數時,都會發生錯誤。如果
InEncoding
為 Unicode 型別,則每當找到以下任一項時,都會發生錯誤:- 大於 16#10FFFF 的整數(最大 Unicode 字元)
- 16#D800 到 16#DFFF 範圍內的整數(為 UTF-16 代理對保留的無效範圍)
不正確的 UTF 編碼。
如果
InEncoding
是其中一種 UTF 型別,則任何二進位檔案中的位元組都必須在該編碼中有效。錯誤可能因各種原因而發生,包括以下原因:
- 「純」解碼錯誤(例如,位元組的高位錯誤)。
- 位元組解碼為太大的數字。
- 位元組解碼為無效 Unicode 範圍中的碼位。
- 編碼為「過長」,表示一個數字應以更少的位元組編碼。
會特別處理截斷的 UTF 情況,請參閱下方有關不完整二進位檔案的段落。
如果
InEncoding
為latin1
,則只要二進位檔案包含整個位元組,就始終有效,因為每個位元組都屬於有效的 ISO Latin-1 範圍。
當未找到任何實際的無效整數或位元組時,但是尾隨的 binary/0
包含的位元組太少而無法解碼最後一個字元時,會發生一種特殊類型的錯誤。如果從檔案中分塊讀取位元組,或者二進位檔案以其他方式在非 UTF 字元邊界上分割,則可能會發生此錯誤。然後,會傳回 incomplete
元組,而不是 error
元組。它包含與 error
元組相同的部分,但標籤為 incomplete
,而不是 error
,並且最後一個元素始終保證為二進位檔案,其中包含(到目前為止)有效的 UTF 字元的第一部分。
如果一個 UTF 字元在 Data
中的兩個連續二進位檔案上分割,則轉換成功。這表示只要將整個範圍指定為輸入而不發生錯誤,就可以從一系列二進位檔案中解碼字元。
範例
decode_data(Data) ->
case unicode:characters_to_list(Data,unicode) of
{incomplete,Encoded, Rest} ->
More = get_some_more_data(),
Encoded ++ decode_data([Rest, More]);
{error,Encoded,Rest} ->
handle_error(Encoded,Rest);
List ->
List
end.
但是,不允許使用非完整位元組的位字串,因此必須沿著 8 位元邊界分割 UTF 字元才能解碼。
在以下情況下會擲回 badarg
例外狀況:
- 任何參數的類型錯誤。
- 列表結構無效(尾部為數字)。
- 二進制數據不包含完整的字節(位元字串)。
-spec characters_to_nfc_binary(chardata()) -> unicode_binary() | {error, unicode_binary(), chardata()}.
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的標準等效複合字元形式。
輸入中的任何二進制數據必須使用 utf8 編碼。
結果是一個 utf8 編碼的二進制數據。
4> unicode:characters_to_nfc_binary([<<"abc..a">>,[778],$a,[776],$o,[776]]).
<<"abc..åäö"/utf8>>
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的標準等效複合字元形式。
輸入中的任何二進制數據必須使用 utf8 編碼。
結果是一個字元列表。
3> unicode:characters_to_nfc_list([<<"abc..a">>,[778],$a,[776],$o,[776]]).
"abc..åäö"
-spec characters_to_nfd_binary(chardata()) -> unicode_binary() | {error, unicode_binary(), chardata()}.
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的標準等效分解字元形式。
輸入中的任何二進制數據必須使用 utf8 編碼。
結果是一個 utf8 編碼的二進制數據。
2> unicode:characters_to_nfd_binary("abc..åäö").
<<97,98,99,46,46,97,204,138,97,204,136,111,204,136>>
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的標準等效分解字元形式。
輸入中的任何二進制數據必須使用 utf8 編碼。
結果是一個字元列表。
1> unicode:characters_to_nfd_list("abc..åäö").
[97,98,99,46,46,97,778,97,776,111,776]
-spec characters_to_nfkc_binary(chardata()) -> unicode_binary() | {error, unicode_binary(), chardata()}.
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的相容等效複合字元形式。
輸入中的任何二進制數據必須使用 utf8 編碼。
結果是一個 utf8 編碼的二進制數據。
4> unicode:characters_to_nfkc_binary([<<"abc..a">>,[778],$a,[776],$o,[776],[65299,65298]]).
<<"abc..åäö32"/utf8>>
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的相容等效複合字元形式。
輸入中的任何二進制數據必須使用 utf8 編碼。
結果是一個字元列表。
3> unicode:characters_to_nfkc_list([<<"abc..a">>,[778],$a,[776],$o,[776],[65299,65298]]).
"abc..åäö32"
-spec characters_to_nfkd_binary(chardata()) -> unicode_binary() | {error, unicode_binary(), chardata()}.
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的相容等效分解字元形式。
輸入中的任何二進制數據必須使用 utf8 編碼。
結果是一個 utf8 編碼的二進制數據。
2> unicode:characters_to_nfkd_binary(["abc..åäö",[65299,65298]]).
<<97,98,99,46,46,97,204,138,97,204,136,111,204,136,51,50>>
根據 Unicode 標準,將可能很深的字元和二進位檔案列表轉換為正規化的相容等效分解字元形式。
輸入中的任何二進制數據必須使用 utf8 編碼。
結果是一個字元列表。
1> unicode:characters_to_nfkd_list(["abc..åäö",[65299,65298]]).
[97,98,99,46,46,97,778,97,776,111,776,51,50]
從提供的 InEncoding
建立 UTF 位元組順序標記 (BOM) 作為二進位檔案。
如果支援 BOM,則預期它會放置在 UTF 編碼檔案或訊息中的最前面。
由於 ISO Latin-1 沒有 BOM,因此該函數對於 latin1
編碼會返回 <<>>
。
請注意,UTF-8 的 BOM 很少使用,而且它實際上不是位元組順序標記。顯然 UTF-8 沒有位元組順序問題,因此 BOM 只是用來區分 UTF-8 編碼和其他 UTF 格式。