在哪里可以找到一组特定的排序规则,用于字符串的相等比较?

我们都知道,使用 String 的 equals() 方法进行相等比较会失败得很惨。相反,应该使用Collator,如下所示:

// 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);

现在,此代码有效,除非 uiLocale 设置为丹麦语,否则结果为 true。在这种情况下,它将产生假。我当然理解为什么会发生这种情况:这只是因为methods是这样实现的:

return compare(s1, s2) == Collator.Equal;

此方法调用用于排序的方法,并检查字符串是否相同。它们不是,因为丹麦语特定的排序规则要求ae之后(如果我正确理解比较方法的结果)对æ进行排序。但是,这些字符串实际上是相同的,具有这种强度,大小写差异和此类兼容性字符(这就是其名称)应被视为相等。

为了解决这个问题,人们将使用RurBasedCollator与适用于相等情况的特定规则集。
最后的问题是:有谁知道我在哪里可以获得这样的特定规则(不仅对于丹麦语,而且对于其他语言),以便兼容性字符,连字等被视为平等(CLDR图表似乎不包含此类规则,或者我搜索失败)?

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


答案 1

我找不到丹麦语的任何现有整理器;丹麦语区域设置的内置版本应该是正确的。我不确定你的假设是否应该用保留进行排序,特别是由于丹麦语中的某些外来词(例如“aerofobi”)(我不是丹麦语使用者,尽管我确实说瑞典语)。aeæ

但是,如果你想将它们排序在一起,似乎你有两种方法可以做到这一点,这取决于你所处的环境。在某些情况下,仅替换字符可能不合适:

String str = "USA lover graekenland støtte";
String sortStr = str.replace("ae", "æ");

另一个,也许更好的选择是您指定的选项;用。使用javadocs中的示例,这是非常微不足道的:RuleBasedCollator

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

然后,您可以使用它:

String test1 = "USA lover Grækenland støtte";
String test2 = "USA lover Graekenland støtte";         // note capital 'G'
boolean result = danishCollator.equals(test1, test2);  // true

如果您认为默认排序规则不正确,则可能希望报告错误。(以前有过类似的错误)。

更新:我用一本印刷的丹麦语百科全书检查了这一点。确实有一些单词以“ae”开头(主要是来自外语的单词;例如,“有氧运动”),它不以“æ”开头的单词排序(因此不等于)。因此,尽管我明白为什么在许多情况下你希望平等地对待他们,但他们并不是严格意义上的。


答案 2

获取特定区域设置的规则的一种方法是使用 getRules 函数。但是,在 Android 中,此函数返回一个空字符串。

    RuleBasedCollator collTemp = (RuleBasedCollator) Collator
            .getInstance(Locale.US);
    String usRules = collTemp.getRules();


    //Save rules in a file
    String rulesPath = "C:\\projects\\droid\\rules.txt";
    BufferedWriter out = new BufferedWriter
            (new OutputStreamWriter(new FileOutputStream(rulesPath),"UTF-16"));
    out.write(usRules);
    out.close();

这些规则与比较函数使用的规则相同。

if (collTemp.compare(target, str) < 0)

注意:我试图将JDK桌面应用程序字符串中的规则插入Android RuleBasedCollator构造函数中,但我得到了U_INVALID_FORMAT_ERROR(仅在Android中)。所以我仍在努力弄清楚如何在Android中获取美国规则。


推荐