2015-09-02 219 views
1

我想了解下面的Java正則表達式程序是如何工作的。我無法理解在程序的輸出的第二行Java正則表達式模式匹配

String line = "This order was placed for QT3000! OK?"; 
     String pattern = "(.*)(\\d+)(.*)"; 
Pattern r = Pattern.compile(pattern); 

    // Now create matcher object. 
    Matcher m = r.matcher(line); 
    if (m.find()) { 
    System.out.println("Found value: " + m.group(0)); 
    System.out.println("Found value: " + m.group(1)); 
    System.out.println("Found value: " + m.group(2)); 

這會產生這樣的

Found value: This order was placed for QT3000! OK? 
Found value: This order was placed for QT300 
Found value: 0 

我理解的輸出,我們在字符串中搜索的模式是一個序列是一個數字(\d+)與之前的所有內容(.*)及之後的內容(.*)。如果我在這裏錯了,請糾正我。

我知道m.group(0)返回整個字符串。我不明白輸出的第二行。 已找到值:該訂單已發給QT300。這裏發生了什麼?

回答

3

它返回從第一個捕獲組(...)產生的匹配。並且由於默認情況下*greedy運算符,它將匹配所有內容,直到字符串中的最後一位數字。

其分解:

enter image description here

m.group(0) → Entire match  → (.*)(\\d+)(.*) // This order was placed for QT3000! OK? 
m.group(1) → Capture Group 1 → (.*)   // This order was placed for QT300 
m.group(2) → Capture Group 2 → (\\d+)   // 0 
m.group(3) → Capture Group 3 → (.*)   // ! OK? 
+0

感謝您的回覆。我能夠理解這是如何與您的解釋 –

1

這是由於雙方的貪婪(儘可能多)和溫順(必要時給予回覆),從正則表達式。 (Greedy... but Docile

  • 但如果定量令牌匹配這麼多字,該模式的其餘部分不能匹配,則發動機將回溯到量化令牌並使其放棄它匹配的字符前面一字符或塊,具體取決於量詞是應用於單個字符還是應用於可匹配多個字符塊的子模式。放棄每個角色或大塊後,引擎再次嘗試匹配模式的其餘部分。我把這種貪婪的量詞稱爲溫順的行爲。

因此,它很好地解釋你到那裏的情況。

  1. 0組:匹配所有
  2. 第一組:[貪婪]匹配所有但將回溯到下面的量化令牌(\ d +)This order was placed for QT300
  3. 第二組(*):(\ d +)[貪婪]至少一位0
  4. 3:(。*)[貪婪] ! OK?

如果你改變了一個無限(\ d +),以零到無限(\ d *)爲了更好地理解,來自第1組的貪婪行爲將採取一切。

+0

感謝您的答覆。我能夠理解這是如何工作的,你的解釋 –

+1

至少標記爲答案/ upvote .... – bLaXjack