java - Java 中跨区域设置的不区分大小写的比较

标签 java localization linguistics

考虑以下 Java 代码比较一个包含 German grapheme ß 的小字符串

String a = "ß";
String b = a.toUpperCase();

assertTrue(a.equalsIgnoreCase(b));

比较失败,因为“ß”.toUpperCase() 实际上等于“SS”,最终导致 equalsIgnoreCase() 中的检查失败。 toUpperCase() 的 Javadocs 确实明确提到了这种情况,但是我不明白为什么这不会转到 ẞ,the capital variant of ß

更一般地说,我们应该如何进行不区分大小写的比较,可能跨不同的语言环境。我们是否应该始终使用 toUpper()equalsIgnoreCase(),而不是同时使用两者?

似乎问题在于 equalsIgnoreCase() 的实现包括以下检查:anotherString.value.length == value.length,这似乎与Javadocs对于 toUpper(),状态为:

Since case mappings are not always 1:1 char mappings, the resulting String may be a different length than the original String.

最佳答案

Java 的 Collator类是为不同语言环境敏感的文本比较操作而设计的。由于“大写”的概念在不同的语言环境之间差异很大,Collat​​or 使用称为比较强度 的更细粒度的模型。提供了四个级别,它们如何影响比较取决于语言环境。

下面是使用 Collat​​or 和德语语言环境对字母 ß 进行不区分大小写比较的示例:

Collator germanCollator = Collator.getInstance(Locale.GERMAN);
int[] strengths = new int[] {Collator.PRIMARY, Collator.SECONDARY,
                             Collator.TERTIARY, Collator.IDENTICAL};

String a = "ß";
String b = "ß".toUpperCase();

for (int strength : strengths) {
    germanCollator.setStrength(strength);
    if (germanCollator.compare(a, b) == 0) {
        System.out.println(String.format(
                "%s and %s are equivalent when comparing differences with "
                + "strength %s using the GERMAN locale.",
                a, b, String.valueOf(strength)));
    }
}

代码打印出来

ß and SS are equivalent when comparing differences with strength 0 using the GERMAN locale.
ß and SS are equivalent when comparing differences with strength 1 using the GERMAN locale.

这意味着德语语言环境认为这两个字符串在 PRIMARYSECONDARY 强度比较中相等。

关于java - Java 中跨区域设置的不区分大小写的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43988852/

相关文章:

python - Python 中的动词时态转换

nlp - winword中汇总功能的背景

java - 椭圆曲线公钥(Java - bouncycaSTLe): How to get 32 byte X and 32 byte Y value from ECPublicKey. toString()

java - Spring 数据中的 Page 映射如何工作?

java - 在对象上使用 setCellValueFactory

ios - 如何在应用程序中加载语言文件(ios swift)

ios - 如何保持本地化 Storyboard 或 XIB 同步?

ios - 为每个目标创建不同的 Localizable 文件

ruby - 如何将单词转换为它们的等效数字?

java - 异步 DoInBackground 在 Listview 下崩溃