2017-06-28 53 views
0

我有以下代碼。當多於一個模式合併時,Matcher.group()不返回正確的值

public class Test { 

    public static void main(String[] args) { 
     Pattern pattern = Pattern.compile("Group1 (.*), Group2=(\\[(.*)\\]|null) ,Group3=\\[(.*)\\] ,Group4=\\[(.*)\\]"); 
     String string = "Group1 12345, Group2=null ,Group3=[group3] ,Group4=[group4]"; 
     Matcher matcher = pattern.matcher(string); 
     matcher.find(); 

     for (int i = 1; i <= matcher.groupCount(); i++) { 
      System.out.println(i + ": " +matcher.group(i)); 
     } 
     System.out.println(); 

     string = "Group1 12345, Group2=[group2] ,Group3=[group3] ,Group4=[group4]"; 

     for (int i = 1; i <= matcher.groupCount(); i++) { 
      System.out.println(i + ": " +matcher.group(i)); 
     } 
    } 
} 

輸出通過上面的代碼給出:

1: 12345 
2: null 
3: null 
4: group3 
5: group4 

1: 12345 
2: null 
3: null 
4: group3 
5: group4 

問題1:爲什麼我得到groupCount 5?是否由於多個正則表達式組合在一起(在Group2)?

問題2:我期望的輸出是

12345 
null 
group3 
group4 

12345 
group2 
group3 
group4 

我應該怎麼做才能打印我期望的方式輸出。

請幫助我正確理解程序。由於

回答

1

爲什麼選擇5組?

Group1 (.*), Group2=(\\[(.*)\\]|null) ,Group3=\\[(.*)\\] ,Group4=\\[(.*)\\] 
    ^  ^^     ^    ^
     1   2 3      4     5 

基本上,你只需要打開算括號的數量。

所以這應該解釋你的第一個輸出。

至於第二個輸出,你的匹配器仍然指向第一個字符串。所以你需要包括:

string = "Group1 12345, Group2=[group2] ,Group3=[group3] ,Group4=[group4]"; 
matcher = pattern.matcher(string); 
matcher.find(); 

最後一個循環之前。

最後,爲了得到期望的輸出,我只想用這個:

Pattern.compile("Group1 (.*), Group2=\\[?(.*?)\\]? ,Group3=\\[(.*)\\] ,Group4=\\[(.*)\\]"); 

這是相當簡單的,但失去的是第2組需要對非空值括號內的事實。如果你想保持這種條件,你需要引入一個條件,如if (matcher.group(3).isEmpty()) { ... }。對於組2

模式說明:

\\[? There may be an opening bracket or not, don't capture it 
(.*?) Capture what's after "Group2=", excluding the brackets 
\\]? There may be a closing bracket or not, don't capture it 

注意,在(.*?)?a lazy operator,是有避免捕獲右括號時有一個。

+0

謝謝@assylias。我很愚蠢,不會添加第二次迭代之前添加的語句。我的要求與您提供的模式完美匹配(我需要在括號內包含非空值)。但是,請您解釋模式\\ [?(。*)\\]? 我無法理解這是如何在我的示例中使用的兩個正則表達式模式的組合。謝謝 – Ravi

+0

我在底部添加了一個解釋 – assylias

+0

很好的解釋!感謝您的快速幫助@assylias – Ravi

1

兩個捕獲組符合您的組2標籤:

(\\[(.*)\\]|null) 
^---------------^ 
    ^--^ 

你可以使用非捕獲組內一個:

(\\[(?:.*)\\]|null) 

或在這種特定的情況下,由於組似乎沒用(不用於以後參考,也不適用於修飾符到一組令牌),您應該刪除它:

(\\[.*\\]|null) 
相關問題