为什么语言环境中包含字符集?

为什么语言环境中包含字符集?

据我了解,POSIX 表示区域设置定义必须包含一种字符编码类型,例如 UTF-8。语言环境通常作为 shell 环境变量来实现。

为什么这两个概念不分开呢?例如,现在我们有多个 en_US 语言环境,具体取决于支持的编码数量。从设计的角度来看,这似乎很混乱且难以扩展,那么其理由是什么呢?

答案1

有些语言,例如中文,可以用多种字符集来书写,并且两种字符集都是正确的。它们有一个更新的、简化的字符集,也有一个更复杂的、传统的字符集。或者蒙古语或塞尔维亚语都可以用西里尔字母或拉丁字母书写。

此外,许多语言的重音字符如 ä、ö 等在不同的编码中具有不同的代码,尽管它们在屏幕上是相同的。因此,将 ä 写入文件意味着您将不同的字节序列写入该文件(如果它是由 utf8 编码的),就好像它是按照不同的标准编码的(在我的示例中,其名称是 iso8859-1 编码)。

此外,还有一些编码可以支持单一或某些语言。例如,iso8859-1支持大多数西欧语言,iso8859-2支持中欧和东欧语言,直到它们是用拉丁文字编写的。 Ascii 仅支持英语,但 utf8 支持世界上几乎所有语言。

因此,语言和可能的编码之间存在多对多的关系:语言可以用多种编码来编码,并且大多数编码可以用于多种语言。

编码兼容性也存在多对多关系:例如,iso8859-2 向上兼容 ascii,但 ebcdic 则不向上兼容。

编码兼容性之间也存在多对多的关系。例如,ebcdic 可以转换为 ascii,但 iso8859-2 则不能。

因此,存在一个由部分兼容的标准组成的复杂网络。实际使用的编码与语言一样完全属于语言环境。因此,它必须像语言一样被处理。这就是为什么它使用相同的环境变量进行处理。

尽管这是可能的,而且在我看来,这是一种更好的方法,如果它由不同的环境变量处理的话。因此,编码作为语言会有一个不同的环境变量,并且它不会是语言字符串的扩展。其原因主要是历史原因、兼容性原因。

但是,至少在 glibc 中,还支持不同的环境变量。这是我的英语 Linux 上的“区域设置”输出的样子:

$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

正如您所看到的,有不同的 LANG 和 LANGUAGE 环境变量。不幸的是,这主要是为了某些标准兼容性,而系统看起来并没有真正遵循它。

扩大:

关于历史:在古代,几乎所有的系统都是美国英语,采用 ASCII 或 EBCDIC 编码。多语言或多编码支持是闻所未闻的,如果开发了它们,他们也会使用临时解决方案(例如,通过覆盖系统固件中的字符集位图)。另外,我当时在 1988 年左右开发了对 c64 的 latin2 字符支持(我只提供了 latin2 的一些字符,但没有提供代码页 - 当时,我什至不知道什么是代码页))。代码页是他们后来的发明,最初是为了标准化 ascii 的类似扩展。在大型机世界中使用的是 ebcdic,它本质上与 ascii 不兼容,也发生了类似的转换(ebcdic 最初是为了使打孔卡易于人类读取而开发的,ascii 的目标是轻松的数据处理)。

所有这些编码都使用 1 个字符代表 1 个字节。在Linux中,多语言支持是在libc4时代(九十年代初)开始的。 Unicode当时还不存在,它是一个新的、未实现的标准,所有的软件都是以1个字符=1个字节的怀疑开发的。为了使 utf 可行,所有这些都应该进行重大修改,这是接下来十年的主要麻烦的根源。

所有语言扩展都使用字节的上半部分(ascii 仅指定 7 位,因此 ä、ö 或西里尔文/希腊文脚本的位置在 128-255 之间)。因此,它们彼此也不相容。因此,当时,语言和代码页之间的关系更像是一对一,就像现在的多对多一样。

因此,支持语言也明确指定了要使用的代码页。因此,不支持不同的代码页,甚至代码页作为术语也没有被广泛接受。你可以想象,当时win95从win31的ibm850切换到cp1251,造成了多少麻烦,而大多数工具甚至不知道codepages的存在。

在 Linux 中,语言仅由 LANG 环境变量中的 2 个字符确定,仅此而已。语言方言支持(例如巴西葡萄牙语的“pt_BR”而不是简单的“pt”)已经是对此的独立扩展。

utf8 迫切需要支持具有多个封装的同一语言。虽然这个问题当时就已经存在了(参见塞尔维亚语,什么可以用西里尔字母书写,也可以用拉丁字母书写),但它只对一些小语言造成麻烦(据我所知,塞尔维亚人只是用拉丁字母书写一切)。因此,多编码支持是持续开发的下一步。因此,它遵循了共同的模式:语言串的进一步延伸。

相关内容