使用 Java API 验证 BCP-47 语言标签

问题描述 投票:0回答:2

据我所知,验证给定的 BCP-47 语言标签是否有效的唯一方法是使用以下惯用法:

private static boolean isValid(String tag) {
  try {
    new Locale.Builder().setLanguageTag(tag).build();
    return true;
  } catch (IllformedLocaleException e) {
    return false;
  }
}

但是,这种方法的缺点是

setLanguageTag
会引发异常,该异常在经常检查区域设置的工作负载中会产生明显的性能开销(在配置文件中)。

setLanguageTag
函数是使用
sun.util.locale
API 实现的,据我所知,这是唯一检查
sun.util.locale.ParseStatus
的地方。

我希望能够做的是使用具有以下语义的方法:

import sun.util.locale.LanguageTag;
import sun.util.locale.ParseStatus;

private static boolean isValid(String tag) {
  ParseStatus sts = new ParseStatus();
  LanguageTag.parse(tag, sts);
  return !sts.isError();
}

但是,无法以上述方式检查语言环境,因为它直接使用

sun.*
类,因为它需要额外的 JDK 选项才能从
sun.util.locale
模块导出
java.base

有没有一种方法可以在不使用私有

sun.*
API 的情况下验证语言标签,同时与
sun.util.locale.LanguageTag#parse
的实现保持一致?

java performance localization
2个回答
0
投票

最简单的解决方案应该是:

boolean isValidBCP47 = "und".equals(Locale.forLanguageTag(tag))

最好的解决方案是利用

java.util.Locale
的过滤来为您处理这个问题。

我们通常需要回退到语言环境。例如;

en-JP
是说英语的人参观日本主题公园时想要的。然而;当 en-JP 不存在时,您可能只想回退到
en
。此外,您的平台可能不支持所有区域设置,需要检查支持的区域设置列表。

使用

com.glide.Locale
您可以执行以下操作:

ArrayList<Locale.LanguageRange> priorityList = new ArrayList<>();
priorityList.add(new Locale.LanguageRange("en-JP"));
priorityList.add(new Locale.LanguageRange("joking")); // invalid tag
priorityList.add(new Locale.LanguageRange("fr")); // unsupported tag
priorityList.add(new Locale.LanguageRange("en"));

ArrayList<String> supportedTags = new ArrayList<>();
supportedTags.add("ja");
supportedTags.add("en-JP");
supportedTags.add("en");

Locale.filterTags(priorityList, supportedTags, Locale.FilteringMode.AUTOSELECT_FILTERING);

// returns ArrayList ["en-JP", "en"]

0
投票

这个问题来晚了,但现在您可以使用BCP47J,一个Java库,它提供了与BCP47语言标签相关的多个功能。

© www.soinside.com 2019 - 2024. All rights reserved.