Unicode 是否有一种非启发式的方法来查找字符串的编码(即列表)?

Unicode 是否有一种非启发式的方法来查找字符串的编码(即列表)?,unicode,encoding,utf-8,erlang,Unicode,Encoding,Utf 8,Erlang,例如,对于IoDevices,可以使用io:getopts/1,但我找不到任何用于普通字符串的方法 比如说, ManPage = os:cmd("man ls"). % [76,83,40,49,41,32,32,32,32,32,32,32,32,32,32,32,32,32,32, % 32,32,32,32,32,32,32,32,32,32|...] io:format("~p~n",[ManPage]). % [76,83,40,4

例如,对于IoDevices,可以使用
io:getopts/1
,但我找不到任何用于普通字符串的方法

比如说,

ManPage = os:cmd("man ls").           
%   [76,83,40,49,41,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
%   32,32,32,32,32,32,32,32,32,32|...]

io:format("~p~n",[ManPage]).         
%   [76,83,40,49,41,(...)

io:format("~ts~n",[ManPage]).
%   LS(1)                   User Commands         LS(1)
%   NAME
%          ls - list directory contents
文档中只提到了启发式方法,但它可能已经过时,因为根据示例
io_lib:format/2
with
~ts
控制字符生成utf-8输出。使用Erlang 18.0进行尝试:

Bullet = "\x{2022}".
%   [8226]

io:format("~ts~n", [Bullet]).
%   •
%   ok
io:format("~ts~n", ["•"]).   
%   •
%   ok

io_lib:format("~ts~n", [Bullet]).
%   [[8226],"\n"]
我知道我可以使用
unicode:characters_to_binary/{1,2,3}
,因为它接受拉丁文1或utf8编码的输入并输出unicode编码的输出,但我很好奇是否还有其他方法

有趣的是,
unicode:characters\u to\u binary/1
可以很好地工作,而
unicode:characters\u to\u list/1
不能(或者我误用了它)

unicode:字符到二进制(手册页)。
%   
unicode:字符到列表(手册页)。
%   [76,83,40|...]
unicode:字符列表(手册页,拉丁文1)。
%{错误,“LS(1)用户命令LS(1”,
[8208,10,32|...]}

不幸的是,只有启发式方法可以确定字符编码。下面简要解释一下原因

也就是说,在上面指定的特定情况下,真正的问题是系统(而不是Erlang)shell的编码设置为什么。我们可以通过直接检查环境来发现这一点(尽管这将是一个特定于平台的解决方案——我是从使用Bash的Debian派生系统编写的):

然而,这是一个相当糟糕的解决方案。它是完全不可移植的,并且不能保证您的环境实际上遵循规则,将一个5字符的语言/区域,然后是一个点,然后将编码放入它的
$LANG
环境变量中。我很确定这不起作用,例如,至少在某些版本的Solar上是的,在AIX上,我认为获得编码的方法是通过检查
$LC_CTYPE
或类似的东西(或者可能是向后的…或者…看,我甚至不记得这方面的怪癖,这足以说明这是不可靠的)

另一种方法是使用
locale
命令,让它直接为您提供字符集:

4> os:cmd("locale charmap").
"UTF-8\n"
那条尾随的新线让我讨厌,所以

5> string:strip(os:cmd("locale charmap"), right, $\n).
"UTF-8"
这就是说,
locale
命令也不存在于任何地方。在任何情况下,检查来自环境和环境变量的区域设置输出数据的某种组合都应该起到作用,尽管为了使其可移植,您需要用一些方法来武装您的系统。幸运的是,现在大多数系统默认为utf8,除了Windows,但至少Windows主要是内部标准化的


(如果您专门处理手册页…请记住,手册页中嵌入了用于标记的控制字符,因此,尽管手册页的纯文本输出将是您所期望的,但由
man
解释的实际手册页数据将被标记。根据您所做的操作,可能更容易操作手册页a。)不清楚我们谈论的是什么编程语言,但是没有这样的方法

您可以要求用户设置环境变量LC_ALL/LC_CTYPE/LANG以匹配数据,但不能确定他们是否真的这样做了


此外,您的程序可能必须在同一个程序运行中处理不同的编码(例如,来自不同的文件),因此您可以使用一些启发式来猜测编码(除了麻烦!),或者为用户提供一种指定编码的方法,就像您打开文件时文本编辑器所做的那样。

原始问题包含在“Erlang”中但它被删掉了。我希望它有一个我不知道的其他语言没有的银弹(我知道这很幼稚,但我必须尝试)。我只是在玩Yaws的本地版本和文档页面上名为
man
的脚本。我认为结果的编码将由shell设置,但我希望是“懒惰的”解决方案。感谢您对环境变量的详细解释,因为到目前为止,我只使用过其他Linux发行版,而没有Unice。
4> os:cmd("locale charmap").
"UTF-8\n"
5> string:strip(os:cmd("locale charmap"), right, $\n).
"UTF-8"