unicode:characters_to_list似乎不适用于utf8列表

时间:2013-10-06 17:15:51

标签: unicode encoding utf-8 erlang

我正在尝试使用Erlang library "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]

没有。为什么会这样?当我在specification中读到时,输入数据可以是二进制或字符列表,所以,就我而言,我正在做的一切。

2 个答案:

答案 0 :(得分:2)

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

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

erlang中没有utf8类型,但您认为byte会接受unicode:characters_to_list/2并且行为正确。

总结一下。在erlang中有两种常用的方法来表示字符串,它们是位串和字符列表。 list of bytesunicode:characters_to_list(Data, InEncoding)编码中将其中一个表示形式(或其组合)中的字符串Data转换为unicode代码点列表。

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

unicode:characters_to_list/2

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

答案 1 :(得分:1)

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

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

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

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