2012-01-05 54 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")); 

} 
相關問題