2015-02-07 56 views
0

我試圖與Java相匹配的重複組:如何在Java中將嵌套重複組與正則表達式匹配?

String s = "The very first line\n" 
     + "\n" 
     + "AA (aa)\n" 
     + "BB (bb)\n" 
     + "CC (cc)\n" 
     + "\n"; 

Pattern p = Pattern.compile(
     "The very first line\\s+" 
     + "((?<gr1>[a-z]+)\\s+\\((?<gr2>[^)]+)\\)\\s*)+", 
     Pattern.DOTALL | Pattern.CASE_INSENSITIVE); 

Matcher m = p.matcher(s); 

if (m.find()) { 
    for (int i = 0; i <= m.groupCount(); i++) { 
     System.out.println("group #" + i + ": [" + m.group(i).trim() + "]"); 
    } 
    System.out.println("group gr1: [" + m.group("gr1").trim() + "]"); 
    System.out.println("group gr2: [" + m.group("gr2").trim() + "]"); 
} 

的問題是與重複的組:雖然正則表達式的整個文本塊匹配(見group #0在下面輸出示例),檢索組#2何時#3(或名稱,以及 - gr1/gr2)它返回只有最後一場比賽(CC/cc),並跳過以前的(AA/aaBB/bb

group #0: [The very first line 

AA (aa) 
BB (bb) 
CC (cc)] 
group #1: [CC (cc)] 
group #2: [CC] 
group #3: [cc] 
group gr1: [CC] 
group gr2: [cc] 

有沒有辦法解決這個問題?

編輯:The very first line是在圖案標識字符串 - 見下文

回答

1

到gknicker的答案的評論好像你想你的模式來匹配整個輸入字符串,但只是個別重複部分。如果這是真的,你的模式將是:

Pattern p = Pattern.compile(
     "((?<gr1>[a-z]+)\\s+\\((?<gr2>[^)]+)\\))", 
     Pattern.CASE_INSENSITIVE); 

那麼在這種情況下,你將有一個while循環找到每一場比賽:

Matcher m = p.matcher(s); 

    while (m.find()) { 
     System.out.println("group gr1: [" 
      + m.group("gr1").trim() + "]"); 
     System.out.println("group gr2: [" 
      + m.group("gr2").trim() + "]"); 
    } 

但是如果你需要整場比賽,你可能會必須使用這樣的兩種模式:

String s = "The very first line\n" 
     + "\n" 
     + "AA (aa)\n" 
     + "BB (bb)\n" 
     + "CC (cc)\n" 
     + "\n"; 

    Pattern p = Pattern.compile(
     "The very first line\\s+(([a-z]+)\\s+\\(([^)]+)\\)\\s*)+", 
     Pattern.CASE_INSENSITIVE); 

    Pattern p2 = Pattern.compile(
     "((?<gr1>[a-z]+)\\s+\\((?<gr2>[^)]+)\\))", 
     Pattern.CASE_INSENSITIVE); 

    Matcher m = p.matcher(s); 
    while (m.find()) { 
     Matcher m2 = p2.matcher(m.group()); 
     while (m2.find()) { 
      System.out.println("group gr1: [" 
       + m2.group("gr1").trim() + "]"); 
      System.out.println("group gr2: [" 
       + m2.group("gr2").trim() + "]"); 
     } 
    } 
+0

感謝您的建議,但我使用「第一行」作爲方向字符串 - 我試圖匹配的文本包含多個部分,有這樣的代表飲食組(對應於相同的模式)。如果我只是「匹配」gr1和gr2,那麼在嘗試匹配它之前我需要提取我需要的塊,否則我會得到不正確的結果 – Laimoncijus 2015-02-07 21:09:37

+0

請參閱我的編輯,以獲得具有兩種模式的替代解決方案。 – gknicker 2015-02-07 22:42:03