首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java.text.Collator将"v“和"w”视为瑞典语/地区的相同字母

java.text.Collator将"v“和"w”视为瑞典语/地区的相同字母
EN

Stack Overflow用户
提问于 2019-02-20 15:03:54
回答 4查看 429关注 0票数 9

以下测试在Java 8中正确通过。

代码语言:javascript
复制
Comparator<String> stringComparator = Collator.getInstance(new Locale("sv", "SE"));

Assert.assertTrue(stringComparator.compare("aaaa", "bbbb") < 0);
Assert.assertTrue(stringComparator.compare("waaa", "vbbb") < 0);
Assert.assertTrue(stringComparator.compare("vaaa", "wbbb") < 0);

这命令waaavbbb之前,vaaawbbb之前。显然,它将vw视为同一个字母。

事实上,根据维基百科,用瑞典语:

到2006年,由于新借词的出现,“W”的使用量有所增加,因此“W”正式成为一个字母,而“V”=“W”的排序规则也被废除。2006年以前的书籍和软件通常使用这一规则。在该规则被废除后,一些书籍和软件继续适用它。

有没有人对此有一个通用的解决办法,使vw在瑞典地区被视为单独的字母?

EN

回答 4

Stack Overflow用户

发布于 2019-02-20 16:16:11

创建您自己的RuleBasedCollator

返回的字符串的值。

代码语言:javascript
复制
((RuleBasedCollator)Collator.getInstance(new Locale("sv", "SE"))).getRules()

并修改它以满足您的需要,然后创建一个新的排序规则和您修改的规则。

也可能提交一个JDK bug报告,以获得良好的效果。

票数 4
EN

Stack Overflow用户

发布于 2019-02-20 16:18:39

这是在vbbb之前的命令和wbbb之前的vaaa。显然,它把v和w看作是同一个字母。

即使在瑞典地区,JDK也不把'w‘和'v’当作相同的字符。字母'v‘在'w’之前。

Assert.assertEquals(1, stringComparator.compare("w", "v"));//TRUE

然而,根据瑞典的排序规则,JDK在“vb”之前命令“wa”。

Assert.assertEquals(1, stringComparator.compare("wa", "vb"));//FALSE

票数 2
EN

Stack Overflow用户

发布于 2019-02-20 16:23:00

您可以创建一个自定义比较器,它封装排序规则,并以您想要的方式手动处理vw

我已经对此进行了两次实现。

第一个是简短而优雅的,它使用了Guavas lexicographical比较器和Holger在评论中提供的棘手的正则表达式。

代码语言:javascript
复制
private static final Pattern VW_BOUNDARY = Pattern.compile("(?=[vw])|(?<=[vw])", Pattern.CASE_INSENSITIVE);

public static Comparator<String> smallCorrectVwWrapper(Comparator<Object> original) {
    return Comparator.comparing(
        s -> Arrays.asList(VW_BOUNDARY.split((String) s)),
        Comparators.lexicographical(original));

第二个实现是一个大而复杂的实现,它可以完成相同的任务,但需要手动实现,而不需要库和正则表达式。

代码语言:javascript
复制
public static Comparator<String> correctVwWrapper(Comparator<Object> original) {
    return (s1, s2) -> compareSplittedVw(original, s1, s2);
}

/**
 * Compares the two string by first splitting them into segments separated by W
 * and V, then comparing the segments one by one.
 */
private static int compareSplittedVw(Comparator<Object> original, String s1, String s2) {
    List<String> l1 = splitVw(s1);
    List<String> l2 = splitVw(s2);

    int minSize = Math.min(l1.size(), l2.size());

    for (int ix = 0; ix < minSize; ix++) {
        int comp = original.compare(l1.get(ix), l2.get(ix));
        if (comp != 0) {
            return comp; 
        }
    }

    return Integer.compare(l1.size(), l2.size());
}

private static boolean isVw(int ch) {
    return ch == 'V' || ch == 'v' || ch == 'W' || ch == 'w';
}


/**
 * Splits the string into segments separated by V and W.
 */
public static List<String> splitVw(String s) {
    var b = new StringBuilder();

    var result = new ArrayList<String>();

    for (int offset = 0; offset < s.length();) {
        int ch = s.codePointAt(offset);

        if (isVw(ch)) {
            if (b.length() > 0) {
                result.add(b.toString());
                b.setLength(0);
            }

            result.add(Character.toString((char) ch));
        } else {
            b.appendCodePoint(ch);
        }

        offset += Character.charCount(ch);
    }

    if (b.length() > 0) {
        result.add(b.toString());
    }

    return result;
}

用法:

代码语言:javascript
复制
public static void main(String[] args) throws Exception {
    Comparator<String> stringComparator = correctVwWrapper(Collator.getInstance(new Locale("sv", "SE")));

    System.out.println(stringComparator.compare("a", "z") < 0);     // true
    System.out.println(stringComparator.compare("wa", "vz") < 0);   // false
    System.out.println(stringComparator.compare("wwa", "vvz") < 0); // false
    System.out.println(stringComparator.compare("va", "wz") < 0);   // true
    System.out.println(stringComparator.compare("v", "w") < 0);     // true
}

实现包装Collator需要做更多的工作,但它不应该太复杂。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54789366

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档