Java 中的跨语言环境比较不区分大小写
Case insensitive comparisons across locales in Java
考虑以下 Java 代码比较包含 German grapheme ß
的小字符串
String a = "ß";
String b = a.toUpperCase();
assertTrue(a.equalsIgnoreCase(b));
比较失败,因为“ß”.toUpperCase() 实际上等于 "SS",最终无法在 equalsIgnoreCase()
中进行检查。 toUpperCase()
的 Java 文档确实明确提到了这种情况,但是我不明白为什么这不会转到 ẞ,the capital variant of ß?
更一般地说,我们应该如何进行不区分大小写的比较,可能跨不同的语言环境。我们是否应该始终使用 toUpper()
或 equalsIgnoreCase()
,而不是同时使用两者?
似乎问题在于 equalsIgnoreCase()
的实施包括以下检查:anotherString.value.length == value.length
,这似乎与 toUpper()
的 Javadocs 不兼容,哪个状态:
Since case mappings are not always 1:1 char mappings, the resulting
String may be a different length than the original String.
Java的Collator
class是为不同语言环境敏感的文本比较操作而设计的。由于 "upper-case" 的概念在语言环境之间差异很大,因此 Collator
使用称为比较 strength 的更细粒度的模型。提供了四个级别,它们如何影响比较取决于语言环境。
下面是一个使用 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 代码比较包含 German grapheme ß
的小字符串String a = "ß";
String b = a.toUpperCase();
assertTrue(a.equalsIgnoreCase(b));
比较失败,因为“ß”.toUpperCase() 实际上等于 "SS",最终无法在 equalsIgnoreCase()
中进行检查。 toUpperCase()
的 Java 文档确实明确提到了这种情况,但是我不明白为什么这不会转到 ẞ,the capital variant of ß?
更一般地说,我们应该如何进行不区分大小写的比较,可能跨不同的语言环境。我们是否应该始终使用 toUpper()
或 equalsIgnoreCase()
,而不是同时使用两者?
似乎问题在于 equalsIgnoreCase()
的实施包括以下检查:anotherString.value.length == value.length
,这似乎与 toUpper()
的 Javadocs 不兼容,哪个状态:
Since case mappings are not always 1:1 char mappings, the resulting String may be a different length than the original String.
Java的Collator
class是为不同语言环境敏感的文本比较操作而设计的。由于 "upper-case" 的概念在语言环境之间差异很大,因此 Collator
使用称为比较 strength 的更细粒度的模型。提供了四个级别,它们如何影响比较取决于语言环境。
下面是一个使用 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
强度比较中相等。