2011-03-31 53 views
1

看起来像一个简单的问题,我需要提取一个捕获组,并可以选择使用分隔字符串限制组。带有可选分隔符的正则表达式捕获组

在下面的例子中,我为“CD”的划界字符串,并期望它会在所有的情况下返回“AB”:“AB”,“ABCD”和“ABCDEFG”

这里是代码:

public static void main(String[] args) { 
    String expected = "ab"; // Could be more or less than two characters 
    String[] tests = {"ab", "abcd", "abcdefg"}; 
    Pattern pattern = Pattern.compile("(.*)cd?.*"); 

    for(String test : tests) { 
     Matcher match = pattern.matcher(test); 
     if(match.matches()) { 
      if(expected.equals(match.group(1))) 
       System.out.println("Capture Group for test: " + test + " - " + match.group(1)); 
      else System.err.println("Expected " + expected + " but captured " + match.group(1)); 
     } else System.err.println("No match for " + test); 
    } 
} 

输出是:


    No match for ab 
    Capture Group for test: abcd - ab 
    Capture Group for test: abcdefg - ab 

我认为在先行可能的工作,但我不认为有一个是可选的(即零个或多个实例)

+0

问题是,即使你制作第一个'(。*)'nongreedy,正则表达式中的其他所有东西 - “(?:cd)'和'。*' - 都是可选的,所以捕获组将会消耗整个字符串会有匹配。你需要使正则表达式更具体。另外,您可以使用[此网页](http://www.regexplanet.com/simple/index.html),而不是为每个测试运行Java程序。 – 2011-03-31 03:06:36

+0

我真的不知道如何才能使正则表达式更具体的给定的要求...期望的字符串的长度可能是一个或多个字符,否则长度限制器将工作,但除此之外,我不知道如何限制它。 – 2011-03-31 03:15:02

+1

仅仅使用'indexOf'和'substring'是不可能的? – Melv 2011-03-31 03:17:14

回答

4

试试这个:

Pattern pattern = Pattern.compile("(.*?)(?:cd.*|$)"); 

.*?是不贪婪,和正则表达式的其余部分或匹配cd其次是什么,或者字符串的结尾。

+0

杰出...谢谢杰森! – 2011-03-31 03:47:55

0

我认为你唯一的问题可能是?只适用于d。改为尝试(cd)?

+0

输出:失败的'abcd'和'abcdefg' – 2011-03-31 02:58:24