考虑以下 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
类是为不同语言环境敏感的文本比较操作而设计的。由于“大写”的概念在不同的语言环境之间差异很大,Collator
使用称为比较强度 的更细粒度的模型。提供了四个级别,它们如何影响比较取决于语言环境。
下面是使用 Collator
和德语语言环境对字母 ß
进行不区分大小写比较的示例:
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.
这意味着德语语言环境认为这两个字符串在 PRIMARY
和 SECONDARY
强度比较中相等。
关于java - Java 中跨区域设置的不区分大小写的比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43988852/