Skip to content

JEP 128: BCP 47 Locale Matching | BCP 47 区域设置匹配

摘要

定义 API,以便使用 BCP 47 语言标签(参见 RFC 5646)的应用程序能够以符合 RFC 4647 的方式将语言标签与用户的语言偏好进行匹配。

动机

跨应用程序、平台和 / 或协议指定一组语言标签(即一系列语言),并将给定的语言标签与这样的集合(例如,用户首选的一组语言)进行匹配,是一种常见的场景。Java SE 8 将根据 RFC 5646 提供完整的 BCP 47 实现。

描述

实现 RFC 4647 中定义的功能,其描述如下:

本文档描述了一种称为“语言范围”的语法,用于指定用户语言偏好列表中的项目。它还描述了将这些与语言标签进行比较和匹配的不同机制。定义了两种匹配机制:过滤和查找。过滤生成一个(可能为空)的语言标签集合,而查找生成一个单一的语言标签。可能的应用包括语言协商或内容选择。

拟议 API 的基本思想是:

  1. 使用 Collection<String> 实现语言范围,使用 List<String> 实现语言优先级列表。

  2. 提供几种方法实现以下功能:

    • 基本过滤:接收基本语言范围和语言优先级列表,并返回过滤后的语言标签集合。
    • 扩展过滤:接收扩展语言范围和语言优先级列表,并返回过滤后的语言标签集合。
    • 查找:接收基本语言范围和语言优先级列表,并返回最佳匹配的语言标签。

示例:这里有一个人的母语是日语(“ja”),第二语言是英语(“en”)和德语(“de”)。他住在日本。并且,这里有一个应用程序,它恰好有英语、法语、新喀里多尼亚爪哇语和日语的本地化资源数据。

使用新 API,上述情况可以表达如下:

java
/* 用户语言优先级列表的基本语言范围:
 *   ja-JP: 在日本使用的日语
 *   en-jp: 在日本使用的英语
 *   de-JP: 在日本使用的德语
 *
 * 顺序表示用户对每种语言的优先级。
 * 请注意,每个子标签(如“jp”)不区分大小写,并在规范化后使用。
 */
List<String> list1 = Arrays.asList("ja-JP", "en-jp", "de-JP");

/* 用户语言优先级列表的扩展语言范围:
 *   ja-*-JP: 在日本使用的日语(不限制区域变体)
 *   en-*-jp: 在日本使用的英语(不限制区域变体)
 *   de-*-JP: 在日本使用的德语(不限制区域变体)
 *
 * 顺序表示用户对每种语言的优先级。
 * 请注意,每个子标签(如“jp”)不区分大小写,并在规范化后使用。
 */
List<String> list2 = Arrays.asList("ja-*-JP", "en-*-jp", "de-*-JP");

/* 应用程序的语言范围:
 *   en-US: 在美国使用的英语
 *   en-JP: 在美国使用的日语(假设)
 *   fr-FR: 在法国使用的法语
 *   de-de: 在德国使用的德语
 *   de-CH: 在瑞士使用的德语
 *   de-jp: 在日本使用的德语
 *   jas-JP: 在日本使用的新喀里多尼亚爪哇语
 *   ja-US: 在美国使用的日语(假设)
 *   ja-Latn-JP: 在日本使用的日语,使用拉丁字母书写
 */
Collection<String> ranges =
    Arrays.asList("en-US", "en-JP", "fr-FR", "de-DE", "de-CH", "de-JP",
                  "ja-US", "jas-JP", "ja-Latn-JP");

// 匹配 1:基本过滤返回“en-JP”和“de-JP”的列表。
List<Locale> tags1 = Locale.filterBasic(list1, ranges);

// 匹配 2:扩展过滤返回“ja-Latn-JP”、“en-JP”和“de-JP”的列表。
List<Locale> tags2 = Locale.filterExtended(list2, ranges);

// 匹配 3:查找返回“en-JP”。
Locale locale = Locale.lookup(list1, ranges);

请注意,此处介绍的 API 是草案,可能稍后更改。