我试图像这样强制使用UTF-8:
to_utf8(X) when is_list(X) ->
unicode:characters_to_binary(X, utf8);
to_utf8(X) when is_binary(X) ->
to_utf8(binary_to_list(X));
to_utf8(X) -> X.
并按照以下方式进行测试:
<<"é"/utf8>> = to_utf8(<<"é">>),
<<"Ø"/utf8>> = to_utf8(<<"Ø">>),
<<"œ"/utf8>> = to_utf8(<<"œ">>),
使用R16B03时,一切正常。但是在升级到Erlang 17.5之后,该函数停止了对“œ”或“”等字符的工作,即使它们在UTF-8中可用
由于R17使用utf-8作为默认编码而不是R16的latin-1,因此这应该与以前相同。
我忽略了什么吗?
谢谢:)
答案 0 :(得分:1)
我将在下面的示例中使用œ
作为示例unicode字符:
<<197,147>> = <<"œ"/utf8>>.
[197,147] = binary_to_list(<<"œ"/utf8>>).
<<195,133,194,147>> = unicode:characters_to_binary(binary_to_list(<<"œ"/utf8>>), utf8).
在R17之前,latin1
的默认编码是允许它与binary_to_list/1
一起使用的。新默认值为unicode
。
列表[197,147]
的格式不符合unicode:characters_to_binary/2
中隐含输出编码unicode
的格式。如果我们想要使用binary_to_list/1
,我们必须指定输出编码应为latin1
,这是R16及以下版本的默认值:
<<197,147>> = unicode:characters_to_binary(binary_to_list(<<"œ"/utf8>>), latin1, latin1).
另一种解决方案是使用unicode:characters_to_list/1
代替binary_to_string
:
[339] = unicode:characters_to_list(<<"œ"/utf8>>).
<<197,147>> = unicode:characters_to_binary(unicode:characters_to_list(<<"œ"/utf8>>), utf8).
更好的解决方案是直接使用unicode:characters_to_binary/1,2,3
,因为不需要将二进制文件转换为列表:
<<"œ"/utf8>> = unicode:characters_to_binary(<<197,147>>).
<<"œ"/utf8>> = unicode:characters_to_binary("œ").