2016-07-06 154 views
5

我有一個ArrayList<String>,我反覆查找給定String的正確索引。基本上,給定一個字符串,程序應該搜索整個單詞並找到整個單詞匹配的索引。例如:Java匹配字符串中的整個單詞

ArrayList<String> foo = new ArrayList<String>(); 
foo.add("AAAB_11232016.txt"); 
foo.add("BBB_12252016.txt"); 
foo.add("AAA_09212017.txt"); 

所以,如果我給字符串AAA,我該回去指數2(最後一個)。所以我不能使用方法,因爲這會讓我回到索引0

我試着用這個代碼:

String str = "AAA"; 
String pattern = "\\b" + str + "\\b"; 
Pattern p = Pattern.compile(pattern); 

for(int i = 0; i < foo.size(); i++) { 
    // Check each entry of list to find the correct value 
    Matcher match = p.matcher(foo.get(i)); 

    if(match.find() == true) { 
     return i; 
    } 
} 

不幸的是,這個代碼永遠不會達到循環內的if聲明。我不確定我做錯了什麼。

注意:如果我搜索的是AAA_0921,全名是AAA_09212017.txt,或者是它唯一的字符串的任何部分,這也應該有效。

+2

'_'被認爲是一個字character..so它不會爲字邊界行動.. – rock321987

+0

哦,我不知道。我會研究另一種表達方式。 – syy

+0

難道你不是指'回報我;'? – 4castle

回答

5

由於單詞邊界不字字符之間並匹配強調你需要

String pattern = "(?<=_|\\b)" + str + "(?=_|\\b)"; 

這裏,(?<=_|\b)正回顧後,需要一個詞邊界或str之前出現下劃線,並且(?=_|\b)正向前查找需要下劃線或字邊界出現在str之後。

請參閱this regex demo

如果你的話可能有內部特殊的字符,你可能想使用一個更直接的字邊界:

"(?<![^\\W_])" + Pattern.quote(str) + "(?![^\\W_])" 

這裏,負回顧後(?<![^\\W_])失敗的比賽,如果有一個字字符,除了一個下劃線([^...]是否定字符類別,它匹配除此類別內定義的字符,範圍等以外的任何字符,因此它匹配除非字詞字符以外的所有字符以及_)和(?![^\W_])負向預覽如果除str之後的下劃線有一個字符字符,則匹配失敗。

請注意,第二個示例具有帶引號的搜索字符串,因此即使AA.A_str.txt也可以與AA.A很好地匹配。

another regex demo

+0

非常感謝!這使它工作。你能解釋表達的不同部分嗎?我對'regex'相當陌生。如果沒有,那沒關係,我可以查看它。 – syy

+1

@Flow一個很棒的工具是[regex101.com](http://www.regex101.com)。如果你看右上方的面板,它解釋你給它的正則表達式。當然,它不支持Java正則表達式,但它通常足夠接近PCRE。 – 4castle

+2

我與火車車廂裏的筆記本電腦爲我的兒子打架,當然我會嘗試:) –

相關問題