2014-11-06 102 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