2017-05-31 28 views
2

在java中,我試圖確定用戶輸入的字符串(意思是我不知道輸入是什麼)恰好被包含在另一個字符串中,在字邊界上。因此the的輸入在文本there is no match中不應匹配。如果輸入字符串中有標點符號,我會遇到問題,並可以使用一些幫助。Java正則表達式與問號和字邊界完全匹配

在沒有標點符號的,這工作得很好:

String input = "string contain"; 
Pattern p = Pattern.compile("\\b" + Pattern.quote(input) + "\\b"); 

//both should and do match 
System.out.println(p.matcher("does this string contain the input").find()); 
System.out.println(p.matcher("does this string contain? the input").find()); 

然而,當輸入中有一個問號,用字邊界匹配似乎不工作:

String input = "string contain?"; 
Pattern p = Pattern.compile("\\b" + Pattern.quote(input) + "\\b"); 

//should not match - doesn't 
System.out.println(p.matcher("does this string contain the input").find()); 

//expected match - doesn't 
System.out.println(p.matcher("does this string contain? the input").find()); 

//should not match - doesn't 
System.out.println(p.matcher("does this string contain?fail the input").find()); 

任何幫助,將不勝感激。

+0

@quackenator通過添加'Pattern.quote()',您不必轉義任何特殊字符 – diginoise

+0

應該'失敗!'與'fail!'匹配(爲避免混淆,留下一個問號) – steffen

+0

好問題@steffen - 是的 - 想要將任何標點符號不直接作爲「字邊界」的一部分輸入 –

回答

2

?之間沒有字邊界,因爲沒有相鄰的單詞字符;這就是爲什麼你的模式不匹配。你可以把它改成這樣:

Pattern.compile("(^|\\W)" + Pattern.quote(input) + "($|\\W)"); 

匹配輸入或非文字字符的開始 - 模式 - 輸入或非單詞字符結束。或者,更好的,你使用負回顧後和負前瞻:

Pattern p = Pattern.compile("(?<!\\w)" + Pattern.quote(input) + "(?!\\w)"); 

這意味着,之前和你的模式後,必須不存在單詞字符。

+0

的評論之後在我的快速測試中,這是行得通的 - 謝謝! –

+0

這是因爲如果中間有'!',這是你的單詞邊界。用你的輸入序列,「這個字符串是否包含?!輸入失敗」,'string contains?!'不匹配,但是'string contains?'做。這是一致的。 – steffen

+0

對不起 - 在我看到您的回覆之前刪除了我的評論,因爲我意識到我的錯誤。還有一件事,如果文本以輸入結尾,它似乎不匹配,所以在這個例子中'字符串是否包含?'會失敗,但是字符串是否包含? '(有空格)很好。其中一天,我會更好地學習我的正則表達式! –

1

您可以使用:

Pattern p = Pattern.compile("(\\s|^)" + Pattern.quote(input) + "(\\s|$)"); 
//---------------------------^^^^^^^----------------------------^^^^^^^ 

絃樂您將獲得:

does this string contain the input  -> false 
does this string contain? the input  -> true 
does this fail the input string contain? -> true 
does this string contain?fail the input -> false 
string contain? the input    -> true 

的想法是,包含您的input + space,或end with your input的字符串相匹配。

+0

部分在右手邊工作,因爲它只匹配'contain?'後的空格,但不是e。 G。另一個'?'。那麼左邊的那個怎麼樣呢? – steffen

+0

hoho這是正確的@steffen,現在呢? –

+0

@steffen你可以嘗試使用'這是否?字符串包含?輸入'它匹配正確,如果'字符串輸入=「?字符串包含?」;' –

0

您使用的是單詞邊界匹配:\b

爪哇正則表達式實現認爲以下字符如文字字符: \w:= [a-zA-Z_0-9]

任何非字字符是簡單地將上述基團 ​​以外的:= [^a-zA-Z_0-9]

字邊界是由過渡[a-zA-Z_0-9][^a-zA-Z_0-9],反之亦然。

對於輸入"does this string contain? the input"和文字圖案\\b\\Qstring contain?\\E\\b的最後一個字邊界\\b落在文本輸入到從?<white space>過渡內,因此不是有效的非單詞也不非字單詞按照上述定義過渡,這意味着它是不是單詞邊界