我在哪里可以找到一组特定的整理规则来进行字符串的相等比较?

Paw*_*yda 15 java localization collation internationalization icu

我们都知道使用String的equals()方法进行相等比较会失败.相反,应该使用Collat​​or,如下所示:

// we need to detect User Interface locale somehow
Locale uiLocale = Locale.forLanguageTag("da-DK");
// Setting up collator object
Collator collator = Collator.getInstance(uiLocale);
collator.setStrength(Collator.SECONDARY);
collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
// strings for equality testing
String test1 = "USA lover Grækenland støtte";
String test2 = "USA lover graekenland støtte";
boolean result = collator.equals(test1, test2);
Run Code Online (Sandbox Code Playgroud)

现在,这段代码有效,除非 uiLocale设置为丹麦语,否则结果为真.在这种情况下,它会产生错误.我当然明白为什么会发生这种情况:这只是因为方法equals是这样实现的:

return compare(s1, s2) == Collator.Equal;
Run Code Online (Sandbox Code Playgroud)

此方法调用用于排序的方法并检查字符串是否相同.它们不是,因为丹麦特定的整理规则要求æ后排序(如果我正确理解比较方法的结果)ae.但是,这些字符串实际上是相同的,具有这种强度的情况差异和这样的兼容性字符(这就是它所谓的)应该被视为相等.

要解决这个问题,可以使用RuleBasedCollat​​or和一组适用于相等情况的特定规则.
最后问题是:有没有人知道我在哪里可以得到这样的特定规则(不仅对丹麦语而且对其他语言也是如此),因此兼容性字符,连字等被视为相等(CLDR 图表似乎不包含这样或者我找不到它)?

或者也许我想在这里做一些愚蠢的事情,我应该使用简单的UCA进行相等比较(请问任何代码示例)?

bee*_*jay 3

我找不到任何现有的丹麦语整理器;丹麦语言环境的内置版本应该是正确的。我不确定您的假设是否ae应该进行排序\xc3\xa6,特别是由于丹麦语中的某些外来词(例如“aerofobi”)(我不是说丹麦语的人,尽管我会说瑞典语)。

\n

但是,如果您想将它们排序在一起,似乎有两种方法可以做到这一点,具体取决于您所处的上下文。在某些上下文中,仅替换字符可能是合适的:

\n
String str = "USA lover graekenland st\xc3\xb8tte";\nString sortStr = str.replace("ae", "\xc3\xa6");\n
Run Code Online (Sandbox Code Playgroud)\n

另一种也许更好的选择是您指定的;使用 RuleBasedCollator。使用 javadocs 中的示例,这非常简单:

\n
String danish = "< a, A < b, B < c, C < d, D < e, E < f, F < g, G < h, H < i, I" +\n                "< j, J < k, K < l, L < m, M < n, N < o, O < p, P < q, Q < r, R" +\n                "< s, S < t, T < u, U < v, V < w, W < x, X < y, Y < z, Z" +\n                "< \\u00E6 = ae," +       // Latin letter ae\n                "  \\u00C6 = AE " +       // Latin letter AE\n                "< \\u00F8, \\u00D8" +     // Latin letter o & O with stroke\n                "< \\u00E5 = a\\u030A," +  // Latin letter a with ring above\n                "  \\u00C5 = A\\u030A;" +  // Latin letter A with ring above\n                "  aa, AA";\nRuleBasedCollator danishCollator = new RuleBasedCollator(danish);\n
Run Code Online (Sandbox Code Playgroud)\n

然后您可以使用:

\n
String test1 = "USA lover Gr\xc3\xa6kenland st\xc3\xb8tte";\nString test2 = "USA lover Graekenland st\xc3\xb8tte";         // note capital \'G\'\nboolean result = danishCollator.equals(test1, test2);  // true\n
Run Code Online (Sandbox Code Playgroud)\n

如果您认为默认整理器不正确,您可能希望报告错误。(以前也有过类似的bug)。

\n

更新:我用印刷版丹麦语百科全书对此进行了检查。确实存在以“ae”开头的单词(主要是外语单词;例如“aerobics”),它们未以“\'\xc3\xa6\”开头的单词排序(因此不等于)。因此,尽管我明白为什么在许多情况下你会想平等地对待它们,但严格来说它们并非如此。

\n