哪种语言标签适合我?如何选择语言和其他子标签?
在HTML和XML里,语言标签用于指示内容的语言。
语言标签由一个或多个用连字符分隔的子标签组成。子标签有多种类型。
BCP代表“当前的最佳实践”(Best Current Practice),是一系列RFC的永久名称,这些RFC的编号可能会更新。描述语言标签语法的最新RFC是RFC 5646,《用于识别语言的标签》(Tags for Identifying Languages),该版本废弃了较旧的RFC 4646、3066和1766。
语言标签语法由IETF的BCP 47定义。过去你需要查阅各种ISO标准中的代码列表才能找到正确的子标签,而现在只需查看IANA语言子标签注册中心即可。下面我们会描述新的语言子标签注册中心。
本文提供了如何选择语言标签的建议。有关BCP 47中定义的概念的概述,请参阅HTML和XML中的语言标签。
创建语言标签所需的所有子标签都在一个位置,即IANA语言子标签注册中心。这个注册中心包含了一个很长的文本文件,有近八千个条目。
语言标签中的第一个(通常是唯一的)子标签永远都是指定语言的,在BCP 47中被称为主要语言子标签(primary language subtag)。我们在本文档中使用这个术语来表示说明语言的子标签,以区别于“语言标签”,因为后者指的是整个标签。
要查找主要语言子标签,请在IANA语言子标签注册中心中搜索该语言的名称。例如,如果你想把某些内容标记为法语,可以在注册中心查找“French”,结果将显示如下所示的记录:
%% Type: language Subtag: fr Description: French Added: 2005-10-16 Suppress-Script: Latn %%
你的搜索将和Description
字段相匹配。你需要检查该记录的类型是否为language
。最终,你要找的是Subtag
字段中的值,也就是fr
。
本文剩下的部分将提供有关选择主要语言子标签和(如果需要的话)其他类型的子标签的建议。请注意,并非所有有关语言标签的决定都是直截了当的。在某些情况下,用法将决定你应该遵循各种可能性中的哪一种。
有一些工具可以在搜索注册中心时提供额外的帮助,比如语言子标签查找工具。
考虑大小写。 按照惯例,主要语言子标签为小写,文字子标签以大写字母开头,并以小写字母继续,地区子标签为大写。不过这只是一个约定,你可以自由使用您喜欢的任意大小写组合。
另一方面,如果你在对大小写敏感的上下文中使用语言标签(例如一些系统的文件名),你应该确保遵循一致的字母大小写策略。对于不区分大小写的系统,建议遵循BCP 47中的约定。
你首先应该选择主要语言子标签,因为通常这就是语言标签所需的全部内容。
永远记住,黄金法则是让语言标签尽可能短。只有在将语言与上下文中的其他内容区分开来时,才需要向语言标签添加更多的子标签。
在寻找主要语言子标签时,需要记住几件事:
你可以在民族语中查找语言信息,并与维基百科中的信息互相对照。民族语使用与BCP 47相同的三字母代码,但你需要将BCP 47的两字母代码转换为对应的ISO 639-3代码,才能通过代码查找语言。(语言子标签查找工具可以为你完成此操作。)
在少数情况下,许多人认为是同一种语言的语言可以有不同的语言代码,例如菲律宾语(Filipino)和他加禄语(Tagalog),或契维语(Twi)和阿肯语(Akan)。注册中心并未指示应该使用哪个代码,但你应该确保在你的应用或上下文中保持一致。
Scope: collection
字段,则这个子标签代表一组存在亲缘关系、在同一地理区域使用或以其他方式相关的语言。
这时你应该去找更具体的子标签,不过子标签注册中心没有为此提供任何指示。
如果没有更具体的子标签,你应该使用这类子标签,而不是使用MUL
(多种语言)或UND
(未定义)。
Scope
字段是macrolanguage
,也就是说这个主要语言子标签包含注册中心中的许多更具体的主要语言子标签。
比如,ku
(库尔德语)是一种宏语言,包含ckb
(中库尔德语)、kmr
(北库尔德语)和sdh
(南库尔德语)。
你可以通过在注册中心搜索Macrolanguage: <这里是子标签的名称>
来找到更具体的子标签。语言子标签查找工具也会自动列出给定宏语言的子标签(示例)。
正如上面的语言组子标签,在大多数情况下你应该尝试使用更明确的子标签,但也有一些重要的例外。在这些情况下,出于向后兼容性的原因,你应该继续使用宏语言子标签。
例如,尽管BCP 47中提到zh
(汉语的宏语言子标签)并没有指定该子标签实际上指的是许多有时互相无法理解的汉语方言中的哪一种,但实际上,绝大多系统会将宏语言子标签与其所包含的子标签中的主要语言相关联——在本例中为cmn
(官话/北方话)。如果你的应用过去使用zh-CN
(中国大陆使用的汉语)甚至zh
来识别官话的话,你可以继续以这种方式使用zh
。如果软件或用户期望使用zh
这样的标签,则使用cmn
或cmn-CN
可能会导致严重的兼容性问题。
而如果你用zh
指代其他汉语方言(例如客家话)的话,你应该使用其对应的语言子标签(如hak
)。
Deprecated
字段,则我们不该使用这个子标签。通常,注册中心会在Preferred-Value
字段中告诉你应使用哪种替代方案。例如,iw
(希伯来语)的子标签记录包含以下两个字段:
Deprecated: 1989-01-01 Preferred-Value: he
这表示你应该用he
表示希伯来语。
过去,在处理ISO代码列表时,有时一个语言有多个代码,可能有一个双字母代码和一个或两个三字母代码。IANA子标签注册中心里没有这种歧义:每种语言只有一个代码。(如果有ISO双字母代码,就使用这个代码,否则使用三字母代码。)注册中心的维护者会根据ISO标准的进展来协调注册中心的更新。
BCP 47规范允许在主要语言子标签之后添加一个三字母子标签,称为扩展语言子标签(extended language subtag)(缩写为extlang)。扩展语言子标签的数量较少,而且每个扩展语言子标签都需要与特定的主要语言子标签一起使用(在扩展语言子标签条目的Prefix
字段中给出)。
目前只有7种主要语言子标签可以和扩展语言子标签一起使用。其中6个的Scope
字段在注册中心中是macrolanguage
(ar
、kok
、ms
、sw
、uz
和zh
),另一个是sgn
。
要考虑的包括:
如果可能,请只使用一个语言子标签,尽可能不使用主要语言子标签+扩展语言子标签。
总会有一个三字母子标签和一个主要语言子标签+扩展语言子标签对等价,那就是扩展语言子标签本身。例如,zh-yue
(广州话)也可以用单个子标签yue
来表示。
唯一的例外是在你的系统已经使用主要语言子标签+扩展语言子标签序列的情况下,为了保持向后兼容性,最好使用zh-yue
而不是yue
。
ar
(阿拉伯语的宏语言子标签)可能比arb
(更具体的子标签,表示标准阿拉伯语)更适合标准阿拉伯语。
同样,在处理占主导地位的语言时,通过删除extlang来替换language+extlang序列比直接使用extlang作为主要语言子标签的向后兼容性通常更好。例如,把ms-zsm
缩减成ms
(马来语的宏语言子标签)有时可能比替换为zsm
(标准马来语)更好。
作为一个例子,Unicode的CLDR数据库使用宏语言zh
表示官话(现代标准汉语),使用ku
表示库尔德语。因此,对于官话,你将使用zh
,而不是cmn
;对于北库尔德语,你将使用ku-Latn
而不是kmr-Latn
。不过CLDR数据库不支持扩展语言子标签,所以需要用yue
而不是zh-yue
来表示广州话。
只有在标签中标明文种会添加一些有用的区分信息时,才应该在语言标签中使用文字子标签。通常这是因为一种语言是用多种文字编写的,或者因为内容被改写成了该语言不常见的文字(人们可能会用ru-Latn
标签来表示用拉丁字母写的俄语)。
文字子标签始终为4个字母,并且必须位于语言或扩展语言子标签之后,其他子标签之前。
选择文字子标签时需要注意如下事项。
uz-Arab
,但对音频来说,就不应该使用Arab
文字子标签。
文字子标签Zxxx
可用于非书面内容,如uz-Zxxx
,因为Zxxx
指的是Code for unwritten documents
(非书面内容),但同样,只有在必须明确这种区别的情况下添加这个子标签才有用。
Suppress-script
字段,内容是某一个文字子标签。例如,en
(英语)的条目包含了:
Suppress-Script: Latn
也就是说不应在英语的语言标签中使用Latn
(拉丁字母)文字子标签。
这是因为几乎所有英语文档都用拉丁字母书写,Latn
并没有添加任何区分信息。不过,如果文档是用拉丁字母和另一种文字(例如盲文Brai
)混合而成的,那么标出这两种文字以帮助内容选择(例如,用于样式规则的应用)可能是有用的。
但请注意,并不是所有与一种文字强相关的语言子标签都有suppress-script字段。即使没有suppress-script,你也不应该假定你需要使用文字子标签。
地区子标签将你选择的语言子标签和某一个特定的地区相关联。地区子标签必须位于语言子标签和文字子标签的后面。
和文字子标签一样,只有当地区子标签在特定上下文中提供的信息可以区分该语言标签和其他语言标签时,才应该使用。
例如,en-GB
对于拼写检查来说可能有用,但ja-JP
中的地区子标签没有太大的用处,除非你想将其与世界其他地区使用的日语进行对比。
地区子标签有两种类型:双字母代码和三数字代码。三数字代码主要用于表示包含多个国家的地区,而不是某个国家。比如,es-ES
表示西班牙使用的西班牙语,而es-419
表示拉丁美洲使用的西班牙语。
避免使用废弃子标签。
检查你想使用的子标签是否已被弃用。和其他类型的子标签一样,注册中心通常会通过Preferred-Value
字段告知应该使用的值。
在某些情况下,废弃记录中没有Preferred-Value
字段,但Comments
字段可能会有建议。例如,在YU
(南斯拉夫)下你能看到:
Deprecated: 2003-07-23 Comments: see BA, HR, ME, MK, RS, or SI
同样,只有在内容上下文中需要将此语言标签和另一个类似标签区分开来时,才应使用变体子标签。
变体子标签包含其他子标签没有包含的区别,通常包括方言、书面变体(例如拼写改革)、标音等等。变体子标签通常为5到8个字符长,可以包含字母和/或数字,但也有一些4位数字的子标签(通常代表年份)。变体子标签必须位于语言、文字和地区子标签之后。
使用变体子标签时要注意的关键点是它们的使用顺序。
检查变体子标签的上下文和顺序。
注册中心的大多数变体子标签记录都有一个或多个Prefix
(前缀)字段。这个字段指示了这个变体通常应该和哪个子标签一起使用。例如,pinyin
通常应在包含子标签zh
和Latn
或子标签bo
和Latn
的语言标签中使用,因为pinyin
条目包含如下内容:
Prefix: zh-Latn Prefix: bo-Latn
如果你有充分的理由,也可以把你的变体子标签和其他子标签一起使用。例如,用cmn-Latn-pinyin
来表示用拼音书写的现代标准汉语是完全没有问题的。
尽管注册中心指定了zh
、bo
和Latn
,但这只是最低要求。还可以在语言标签中(在合适的情况下)加入其他子标签,如地区子标签:zh-Latn-CN-pinyin
。
再比如,变体子标签1994
的条目包含:
Prefix: sl-rozaj-biske
这表明它应用在已经有另外两个变体子标签rozaj
和biske
的语言标签中。前缀字段中指定的任何变体子标签都需要位于你刚刚找到的的变体之前。
有一些的变体子标签没有前缀字段,如fonipa
(国际音标)。这类变体应出现在所有具有前缀信息的变体子标签之后。
如果你计划使用多个不带前缀的变体,请按照重要性递减的顺序对它们进行排序。如果它们同等重要,请按字母顺序排列,这将有助于互操作性。
扩展子标签是扩展语言标签的单字符子标签。迄今为止,只有一个扩展子标签:子标签u
由Unicode联盟注册,用于添加有关语言(language)或区域设置(locale)行为的信息。许多区域设置标识符需要针对语言、文化、地区或其他因素进行额外“定制”。该扩展提供了一种在语言标签内使用这些附加定制并进行一般交换的机制。
例如,以下内容表示应用应该使用电话本中的排序规则。
de-DE-u-co-phonebk
u-
扩展在RFC 6067中定义,而RFC 6067指向Unicode联盟的公共区域设置数据存储库(Common Locale Data Repository, CLDR),以获取有关其后面的子标签的详细信息,BCP 47并未定义它。
私用子标签不会出现在注册中心,而是由使用它们的各方之间的私人协议制定和维护。它们由单字符子标签(singleton)x
引入。请注意,单字符子标签之后的任何子标签的长度都不能超过8个字符,但可以使用多个子标签。
私用子标签应谨慎使用,并尽可能避免,因为它们会干扰BCP 47旨在促进的互操作性。
作为私用子标签的例子,en-US-x-twain
可以表示特定类型的美国英语,但仅限于一个封闭社区内。在该私人协议之外,不能依赖其含义。
阅读BCP 47了解更多信息:
旧版标签(grandfathered tag)是为了向后兼容而提供的特殊标签。它们是在RFC 4646之前注册的标签,无法完全由当前注册中心中的子标签组成,或者不符合当前为语言标签定义的语法。
几乎所有旧版标签都已经被注册中心中的子标签或一系列子标签所取代。此类旧版标签现已弃用,通常有一个Preferred-Value
字段,指示用户该如何表示这个语言。比如,注册中心中的旧版标签art-lojban
条目中提到你应该使用jbo
语言子标签。
请注意,旧版标签的前面和后面不应附加其他子标签。