Java字符串搜索忽略重音符号

37

我正尝试为我的应用程序编写过滤器函数,该函数将获取一个输入字符串并过滤掉与给定输入不匹配的所有对象。最简单的方法是使用String的contains方法,即只需检查对象(对象中的字符串变量)是否包含在过滤器中指定的字符串,但这不会考虑到重音符号。

所涉及的对象基本上是人员,而我正在尝试匹配的字符串是名称。例如,如果有人搜索Joao,我希望结果集中包括Joáo。我已经在我的应用程序中使用了Collator类来按名称排序,并且它的工作效果很好,因为它可以进行比较,即使用英国语言区域设置á在b之前但在a之后。但显然,如果您比较a和á,它不会返回0,因为它们不相等。

那么,有没有人有任何想法如何做到这一点呢?


可能是Java。在比较字符串时忽略重音符号的重复问题。 - Barett
3个回答

98

使用java.text.Normalizer和正则表达式消除变音符号

public static String removeDiacriticalMarks(String string) {
    return Normalizer.normalize(string, Form.NFD)
        .replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
}

你可以按照以下方式使用:

String value = "Joáo";
String comparisonMaterial = removeDiacriticalMarks(value); // Joao

2
我撤回我的答案!从未接触过java.text.Normalizer,感谢您的提示。 - brabster
1
这是一个糟糕的答案。你需要使用ICU Collator类创建一个比较强度设置为PRIMARY的排序器对象。这个答案展示了如何从Perl的角度来实现这一点。 - tchrist
1
https://dev59.com/JmTWa4cB1Zd3GeqPC2aj - mark
https://dev59.com/EHE95IYBdhLWcg3wSsCD - Benny Bottema
1
Collator不能用于在字符串中搜索,只能用于比较完整的字符串,在搜索时不起作用(除了精确匹配!)Normalizer效果很好,但速度较慢,适用于单个值,但不适用于在大量值中进行搜索。 - RiRomain
显示剩余2条评论

4

如果你配置Collator忽略重音符号,它会将a和á视为相等,返回0。

public boolean isSame(String a, String b) {
    Collator insenstiveStringComparator = Collator.getInstance();
    insenstiveStringComparator.setStrength(Collator.PRIMARY);
    // Collator.PRIMARY also works, but is case senstive
    return insenstiveStringComparator.compare(a, b) == 0;
}

现在,isSame("a", "á") 的结果为true。

这只匹配精确等效字符串,但如果你想使用“包含”,这不起作用。 - Alejandro Cumpa

0

我编写了一个类,可以通过忽略变音符号(而不是删除它们)来搜索阿拉伯文本。也许你可以从中得到灵感或以某种方式使用它。

DiacriticInsensitiveSearch.java


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接