2017-05-26 125 views
3

我想知道在java中使用matcher的行爲。Java使用正則表達式在字符串中查找值

我有一個模式,我編譯和通過匹配器的結果運行時,我不明白爲什麼缺少一個特定的值。

我的代碼:

String str = "star wars"; 
Pattern p = Pattern.compile("star war|Star War|Starwars|star wars|star wars|pirates of the caribbean|long strage trip|drone|snatched (2017)"); 
Matcher matcher = p.matcher(str); 
while (matcher.find()) { 
     System.out.println("\nRegex : " matcher.group()); 
    } 

我被擊中了「星戰」,這是正確的,因爲它是在我的模式。

但是我並沒有將「星球大戰」當成一擊,我不明白爲什麼它是我的模式的一部分。

+3

交替組中匹配「勝利」的第一個替代方案,其餘未被選中。一旦「星際戰爭」匹配,文本被消耗,就不會有更多的通行證。預計。你需要什麼行爲? –

+0

有沒有辦法返回所有匹配? –

+3

您將不得不單獨檢查每個模式,而不要將其作爲長鏈改變。 – NAMS

回答

2

由於NFA正則表達式中的alternation是「渴望」,即第一個匹配獲勝,而其餘替代方法甚至沒有經過測試,所以這種行爲是預期的。此外,請注意,一旦正則表達式引擎在消費模式中發現匹配(並且您的消費模式不是零寬度斷言,如前瞻/ lookbehind/word邊界/錨點),則索引將提前到從該位置搜索比賽和下一場比賽。

因此,一旦您的第一個star war替代分支匹配,無法匹配star wars,因爲正則表達式索引在最後s之前。

只是檢查如果字符串包含您覈對弦,最簡單的方法是用一個循環:

String str = "star wars"; 
String[] arr = {"star war","Star War","Starwars","star wars","pirates of the caribbean","long strage trip","drone","snatched (2017)"}; 
for(String s: arr){ 
    if(str.contains(s)) 
     System.out.println(s); 
} 

Java demo

順便說一句,你的正則表達式中包含snatched (2017),和它不匹配(),它只匹配snatched 2017。要匹配文字括號,必須轉義()。我還爲star wars刪除了一個隱藏條目。

+0

這種方法是更好,但是我們還應該在'|'上分割字符串並完全匹配'str',以避免像AI這樣的電影出現問題。 – steffen

+0

@steffen:我用'\ |'分割,只是爲了快速構建一個數組。我認爲最好的方法是像往常一樣定義它,用'String [] arr = {「term1」,「term2」,「etc。」};'。注意我甚至沒有刪除笨蛋,我想這些都是在設計時提供的。 –

+0

我決定編輯答案以顯示應該如何定義搜索項的數組。用'「\\ |」'分割是hacky。 –

0

要匹配整個輸入序列,所以你應該使用Matcher.matches()或添加^$

Pattern p = Pattern.compile("^(star war|Star War|Starwars|star wars|" 
     + "star wars|pirates of the caribbean)$"); 

將打印

Regex : star wars 

但我@NAMS同意:不要像這樣構建你的正則表達式。

1

一種更好的方式來建立你的正則表達式將是這樣的:

String pattern = "[Ss]tar[\\s]{0,1}[Ww]ar[s]{0,1}"; 

打破:

  • [SS]:它會在第一位置
  • 匹配或者S或S
  • \ s:表示空間
  • {0,1}

    String pattern = "[Ss]tar[\\s]?[Ww]ar[s]?"; 
    
    • :前一字符(或設置)將0至1倍

    另一種方法是相匹配?:前一字符(或設置)將被一次或不匹配,在所有

有關詳細信息,請參閱https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

編輯1:固定錯字(\s - >\\s)。謝謝,@eugene。

+0

''\\\\\\\\\\\\\\\\\\\\\\\\'''{\\\\\\\\\\\\\\\\''')可能會有很多空格,可能是 – Eugene

+0

尤金:*會導致匹配0次或更多次。通過使用{0,1}它只表示匹配0或1次。 – luizfzs

+0

@Eugene - '\'s *'將允許像'星球大戰'這樣的事物相匹配。 – marklark

相關問題