2012-01-05 41 views
11

我必须测试一个字符串是否包含在另一个字符串中,但不考虑大小写或重音符号(在这种情况下是法语的重音符号)。contains with collat​​or

例如,如果我在字符串"Vallée du Rhône"中搜索"rhone",函数必须返回true

Collat​​or对于带重音符的字符串比较很有用,但不提供contains函数。

有没有简单的方法来完成这项工作?一个正则表达式可能?

其他信息:
我只是需要一个true/false返回值,我不关心比赛的数量或引用字符串测试字符串的位置。

+0

不幸的是,java.util.regex中不支持整理顺序,否则你可能确实试图反对'\ BRH比赛[= O =] NE \ B' ... – fge 2012-01-05 16:10:04

回答

16

您可以使用Normalizer将字符串缩减为可以直接比较的精简版本。

编辑:要清楚

String normalized = Normalizer.normalize(text, Normalizer.Form.NFD); 
String ascii = normalized.replaceAll("[^\\p{ASCII}]", ""); 
0

正常的方式做,这是两个字符串转换不带重音为小写,然后使用标准“包含”。

10

看一看Normalizer

您应该使用Normalizer.Form.NFD作为第二个参数来调用它。

所以,这将是:

Normalizer.normalize(yourinput, Normalizer.Form.NFD) 
    .replaceAll("\\p{InCombiningDiacriticalMarks}+", "") 
    .toLowerCase() 
    .contains(yoursearchstring) 

将返回true,如果匹配(当然的,否则为false)

+1

这会不会将'è'分解为'e''?这将使得包含()失败,除非重音字符总是字符串的最后一个。 – Viruzzo 2012-01-05 16:40:16

+0

糟糕!正确。固定。 – fge 2012-01-05 16:44:21

3

这个怎么样?

private static final Pattern ACCENTS_PATTERN = Pattern.compile("\\p{InCombiningDiacriticalMarks}+"); 

public static boolean containsIgnoreCaseAndAccents(String haystack, String needle) { 
    final String hsToCompare = removeAccents(haystack).toLowerCase(); 
    final String nToCompare = removeAccents(needle).toLowerCase(); 

    return hsToCompare.contains(nToCompare); 
} 

public static String removeAccents(String string) { 
    return ACCENTS_PATTERN.matcher(Normalizer.normalize(string, Normalizer.Form.NFD)).replaceAll(""); 
} 

public static void main(String[] args) { 
    System.out.println(removeAccents("Vallée du Rhône")); 
    System.out.println(removeAccents("rhone")); 
    System.out.println(containsIgnoreCaseAndAccents("Vallée du Rhône", "rhone")); 

}