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

时间:2011-12-05 18:17:56

标签: java localization internationalization collation icu

我们都知道使用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设置为丹麦语。在这种情况下,它会产生错误。我当然理解 为什么 这发生了:这只是因为方法equals是这样实现的:

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

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

要解决这个问题,可以使用RuleBasedCollator一套适用于相等案例的特定规则 最后问题是:有没有人知道我可以在哪里获得这样的特定规则(不仅对丹麦语而且对其他语言也是如此),以便兼容性字符,连字等被视为相等(CLDR {{ 3}}似乎没有包含这样或我搜索失败的那些)?

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

2 个答案:

答案 0 :(得分:3)

我找不到丹麦现有的Collat​​or;丹麦语区域内置的应该是正确的。我不确定您ae应该与æ进行排序的假设,特别是由于丹麦语中的某些外来词(例如"aerofobi")(我不是丹麦语发言人,尽管我说瑞典语。)

但是,如果你想要将它们排序在一起,看起来你有两种方法可以做到这一点,具体取决于你所处的环境。在某些情况下,只更换字符可能是适当的:

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

另一个,或许更好的选择是你指定的那个;使用RuleBasedCollator。使用javadocs中的示例,这非常简单:

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

如果您认为默认展开器不正确,您可能希望report a bug。 (之前有similar bugs)。

更新:我使用印刷的丹麦语百科全书检查了这一点。确实有一个单词以'ae'开头(主要是来自外语的单词;例如“有氧运动”),这些单词与'æ'开头的单词排序(因此不等于)。因此,虽然我知道为什么你想在许多情况下将它们视为平等,但它们并非严格如此。

答案 1 :(得分:0)

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

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

这些规则与比较功能使用的规则相同。

@Override
public boolean isCellEditable(int i, int y) {
   return true;
}

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