2014-11-06 89 views
3

最近我一直在使用Java中的正則表達式,並且發現自己陷入了一個問題(理論上)很容易解決,但是如果有更簡單的方法來解決問題,我就會徘徊(是的,是的,我懶),問題是捕獲一組多次,這就是:捕獲組多次

public static void main(String[] args) { 
    Pattern p = Pattern.compile("A (IvI(.*?)IvI)*? A"); 
    Matcher m = p.matcher("A IvI asd IvI IvI qwe IvI A"); //ANY NUMBER of IvI x IvI 
    //Matcher m = p.matcher("A A"); 
    int loi = 0; //last Occurrence Index 
    String storage; 
    while (loi >= 0 && m.find(loi)) { 
     System.out.println(m.group(1)); 
     if ((storage = m.group(2)) != null) { 
      System.out.println(storage); 
     } 
     //System.out.println(m.group(1)); 
     loi = m.end(1); 
    } 
    m.find(); 
    System.out.println("2 opt"); 
    Pattern p2 = Pattern.compile("IvI(.*?)IvI"); 
    Matcher m2 = p2.matcher(m.group(1)); //m.group(1) = "IvI asd IvI IvI qwe IvI" 
    loi = 0; 
    while (loi >= 0 && m2.find(loi)) { 
     if ((storage = m2.group(1)) != null) { 
      System.out.println(storage); 
     } 
     loi = m2.end(0); 
    } 
} 

使用ONLYPattern p有沒有什麼辦法讓裏面是什麼IvI's(在測試字符串中將是「asd」和「qwe」),考慮到可能有任何數量的IvI's部分,類似於我在第一次嘗試做的事情,即找到該組的第一次出現,然後移動索引和搜索的下一組等等等等...

使用我在寫的同時返回asd IvI IvI qwe爲2組,不只是asd然後qwe代碼,這部分我假設它可能是因爲(。*?)的一部分,不應該是貪婪的,但它仍然會消耗IvI's中的兩個,我提到這一點,否則我可能會使用結束索引那些與matcher.find(anInt)方法,但它也不工作;我不認爲這是正確的正則表達式的任何錯誤,因爲下一個代碼不消耗IvI

public static void main(String[] args) { 
    Pattern p = Pattern.compile("(.*?)IvI"); 
    Matcher m = p.matcher("bla bla blaIvI"); 
    m.find(); 
    System.out.println(m.group(1)); 
} 

此打印:bla bla bla

有一個解決方案我知道(但我懶記得)

(此外,第一代碼,波紋管「2選擇」消息) 的解決方案是BTW將其劃分爲子組,並在那裏你處理只有那些子組一個同時使用另一個正則表達式...

:我做功課 在this頁它提到

由於具有量詞的捕獲組保留其編號,因此當您檢查組時引擎會返回什麼值?所有引擎都會返回捕獲的最後一個值例如,如果您將字符串A_B_C_D_與([A-Z] )+匹配,則當您檢查匹配時,組1將是D。除了.NET引擎之外,所有中間值都會丟失。從本質上講,組1每次匹配時都會被覆蓋。

但我還是希望你給我一個好消息......

+1

什麼是您預期的結果在這種情況下:'一個IVI一個IVI IVI IVI b IVI A'這種情況下'一個IVI一個IVI IVI b IVI一個IVI一個IVI IVI b IVI A'?請注意,與第二步正則表達式「IvI(。*?)IvI」匹配的第二步不適用於第一種情況。在第二種情況下,它是我使用此方法構建正則表達式時使用的測試用例之一:http://stackoverflow.com/questions/15268504/collapse-and-capture-a-repeating-pattern-in-a-單正則表達式/ 15418942#15418942 – nhahtdh 2014-11-06 09:09:36

+0

對於第一種情況,我將能夠得到一個,然後一個「」[空間],然後我不會找不到另一對IvI,字符串不匹配b後的模式,第二次我會得到一個,然後b和第二個匹配的模式,它會在那裏停止 – Ordiel 2014-11-06 16:55:58

+0

我不問你的代碼。如果發生這些情況,我會問你想要的結果。 – nhahtdh 2014-11-06 16:59:23

回答

5

不,不幸的是,你的引文已經提到,在java.util.regex中的正則表達式實現不支持獲取以前的任何值在一場比賽之後重複奪取小組。如您的代碼所示,獲取這些內容的唯一方法是find()多次匹配正則表達式的重複部分。

我也一直在尋找在Java正則表達式的其他實現,例如:

,但我找不到任何支持它(僅適用於微軟.NET發動機)。如果我理解正確,基於狀態機的正則表達式的實現不能輕易實現此功能。雖然java.util.regex不使用狀態機。

如果有人知道支持此行爲的Java正則表達式庫,請分享它,因爲它是一個強大的功能。

p.s.我花了相當長的一段時間來理解你的問題。標題很好,但身體讓我困惑,我是否正確地理解了你。

+0

謝謝,對不起,我會盡量保持簡單;) – Ordiel 2014-11-14 16:02:21