JEP 128:Unicode BCP 47 语言环境匹配
概述
动机
在各种应用程序、平台和/或协议中,一个常见的场景是需要指定一组语言标签(即一系列语言),并将给定的语言标签与该集合进行匹配,例如,用户偏好的语言集合。Java SE 8 将根据 RFC 5646 提供完整的 BCP 47 实现。
描述
实现 RFC 4647 中定义的功能,其描述如下:
本文档描述了一种称为“语言范围”的语法,用于指定用户语言偏好列表中的项目。它还描述了用于比较和将这些项目与语言标签进行匹配的不同机制。定义了两种匹配机制:过滤和查找。过滤产生一组(可能为空)语言标签,而查找则产生单个语言标签。可能的应用包括语言协商或内容选择。
要提出的 API 的基本思想是:
- 使用
Collection<String>
实现语言范围(Language Range),并使用List<String>
实现语言优先级列表(Language Priority List)。 - 提供一些方法实现以下功能:
- 基本过滤:接收基本语言范围(Basic Language Range)和语言优先级列表(Language Priority List),返回经过过滤的语言标签(Language Tags)集合。
- 扩展过滤:接收扩展语言范围(Extended Language Range)和语言优先级列表(Language Priority List),返回经过过滤的语言标签(Language Tags)集合。
- 查找:接收基本语言范围(Basic Language Range)和语言优先级列表(Language Priority List),返回最佳匹配的语言标签(Language Tag)。
示例:这里有一个以日语(“ja”)为母语、英语(“en”)和德语(“de”)为第二语言的人。他住在日本。而且,这里有一个应用程序,恰好拥有英语、法语、新喀里多尼亚爪哇语和日语的本地化资源数据。
上述情况可以使用新的 API 表达如下:
/* Basic language ranges for this user's language priority list:
* ja-JP: Japanese used in Japan
* en-jp: English used in Japan
* de-JP: German used in Japan
*
* The order expresses the priority of each language for the user.
* Note that each sub tag (e.g. "jp") are case insensitive and used after
* normalization.
*/
List<String> list1 = Arrays.asList("ja-JP", "en-jp", "de-JP");
/* Extended language ranges for this user's language priority list:
* ja-*-JP: Japanese used in Japan
* en-*-jp: English used in Japan
* de-*-JP: German used in Japan
*
* The order expresses the priority of each language for the user.
* Note that each sub tag (e.g. "jp") are case insensitive and used after
* normalization.
*/
List<String> list2 = Arrays.asList("ja-*-JP", "en-*-jp", "de-*-JP");
/* The app's language ranges:
* en-US: English used in the USA
* en-JP: Japanese used in the USA
* fr-FR: French used in France,
* de-de: German used in Germany
* de-CH: German used in Switzerland
* de-jp: German used in Japan
* jas-JP: New Caledonian Javanese used in Japan
* ja-US: Japanese used in the USA
*/ ja-Latn-JP: Japanese used in Japan, written in Latin alphabet
Collection<String> ranges =
Arrays.asList("en-US", "en-JP", "fr-FR", "de-DE", "de-CH", "de-JP",
"ja-US", "jas-JP", "ja-Latn-JP");
// Matching 1: Basic filtering returns a list of "en-JP" and
// "de-JP".
List<Locale> tags1 = Locale.filterBasic(list1, ranges);
// Matching 2: Extended filtering returns a list of "ja-Latn-JP",
// "en-JP", and "de-JP".
List<Locale> tags2 = Locale.filterExtended(list2, ranges);
// Matching 3: Look up returns "en-JP".
Locale locale = Locale.lookup(list1, ranges);
</code>
请注意,这里介绍的 API 是草案,可能稍后会发生变化。