1

我正在尝试使用Erlang 库“unicode”将 UTF-8 字符串转换为 Unicode(代码点)列表。我的输入数据是字符串“АБВ”(俄罗斯字符串,正确的 Unicode 表示为 [1040,1041,1042]),已编码在 UTF-8 中。当我运行以下代码时:

1> unicode:characters_to_list(<<208,144,208,145,208,146>>,utf8).
[1040,1041,1042]

它返回正确的值,但如下:

2> unicode:characters_to_list([208,144,208,145,208,146],utf8).  
[208,144,208,145,208,146]

才不是。为什么会发生?正如我在规范中读到的,输入数据可以是二进制或字符列表,所以,就我而言,我做的一切都是正确的。

4

2 回答 2

3

该函数的签名是unicode:characters_to_list(Data, InEncoding),它期望Data是包含编码中InEncoding编码的字符串的二进制文件,或者可能是字符(代码点)和编码中的二进制文件的深层列表InEncoding。它返回 unicode 字符列表。erlang 中的字符是整数。

当您调用unicode:characters_to_list(<<208,144,208,145,208,146>>, utf8)unicode:characters_to_list([1040,1041,1042], utf8)它正确解码 unicode 字符串时(是的,只要Data是整数列表,第二个就是 noop)。但是当你调用unicode:characters_to_list([208,144,208,145,208,146], utf8)erlang 时认为你在编码中传递了 6 个字符的列表utf8,因为它已经是 unicode,所以输出将完全相同。

erlang中没有byte类型,但您假设它unicode:characters_to_list/2会接受list of bytes并且行为正确。

把它们加起来。在 erlang 中有两种常用的表示字符串的方法,它们是位串和字符列表。在编码中采用这些表示之一(或它们的组合)中的unicode:characters_to_list(Data, InEncoding)字符串并将其转换为 unicode 代码点列表。DataInEncoding

如果您有[208,144,208,145,208,146]示例中的列表,则可以使用将其转换为二进制文件erlang:list_to_binary/1,然后将其传递给unicode:characters_to_list/2,即

1> unicode:characters_to_list(list_to_binary([208,144,208,145,208,146]), utf8).
[1040,1041,1042]

unicode模块仅支持 unicode 和 latin-1。因此,(因为函数需要 unicode 或 latin-1 的代码点)characters_to_list在代码点的平面列表的情况下不需要对 list 做任何事情。但是,列表可能很深(unicode:characters_to_list([[1040],1041,<<1042/utf8>>]).)。这是支持Data参数列表数据类型的原因。

于 2013-10-06T19:17:06.323 回答
1

<<208,144,208,145,208,146>>是一个 UTF-8 二进制文件。

[208,144,208,145,208,146]是字节列表(不是代码点)。

[1040,1041,1042]是代码点列表。

您正在传递一个字节列表,但该函数需要一个字符列表或二进制文件。

于 2013-10-06T18:08:53.410 回答