Java、正则表达式、嵌套可选组

Java、正则表达式、嵌套可选组,java,regex,Java,Regex,我试图在Java中捕获嵌套的可选组,但没有成功 我试图捕获一个关键字,后跟一个时间间隔,其中一个关键字现在是任何东西,而时间间隔只是两个日期。间隔可以是可选的,两个日期也可以是可选的。因此,以下是有效的匹配项 话 word[01/01/1900,] word[,01/01/2000] word[01/01/1900,01/01/2000] 我想捕获关键字和两个日期,即使它们为空 这就是我提出的Java MWE public class Parser { public static v

我试图在Java中捕获嵌套的可选组,但没有成功

我试图捕获一个关键字,后跟一个时间间隔,其中一个关键字现在是任何东西,而时间间隔只是两个日期。间隔可以是可选的,两个日期也可以是可选的。因此,以下是有效的匹配项

  • word[01/01/1900,]
  • word[,01/01/2000]
  • word[01/01/1900,01/01/2000]
我想捕获关键字和两个日期,即使它们为空

这就是我提出的Java MWE

public class Parser {
    public static void main(String[] args) {
        Parser parser = new Parser();
        String s = "word [01/01/1900, 01/01/2000]";
        parser.parse(s);
    }

    public void parse(String s) {
        String date = "\\d{2}/\\d{2}/\\d{4}";
        String interval = "\\[("+date+")?, ("+date+")?\\]";
        String keyword = "(.+)( "+interval+")?";
        Pattern p = Pattern.compile(keyword);
        Matcher m = p.matcher(s);
        if (m.matches()) {
            for (int i = 0; i <= m.groupCount(); ++i) {
                System.out.println(i + ": " + m.group(i));
            }
        }
    }
}
如果interval不是可选的,那么它可以工作

String keyword = "(.+)( "+interval+")";

0: word [01/01/1900, 01/01/2000]
1: word
2:  [01/01/1900, 01/01/2000]
3: 01/01/1900
4: 01/01/2000
如果interval是不匹配的组(但仍然是可选的),则它不起作用

String keyword = "(.+)(?: "+interval+")?";

0: word [01/01/1900, 01/01/2000]
1: word [01/01/1900, 01/01/2000]
2: null
3: null
我需要做什么才能找回这两个日期?多谢各位


编辑:第2部分

假设现在我观察匹配重复的关键字。i、 e.正则表达式,
关键字(,关键字)*
。我试过了,但只捕获了第一个和最后一个实例

为了简单起见,假设我想将下面的
a,b,c,d
与正则表达式
([a-z])(?:,([a-z])*

但是,我只能取回第一组和最后一组

0: a, b, c, d
1: a
2: d
为什么会这样


刚刚发现这是不可能的

关键字的第一部分从
(.+)
更改为
(.+?)

没有
(.+)
是贪婪的量词。这意味着它将尽可能地匹配。我不知道正则表达式引擎如何工作的所有机制,但我相信在您的例子中,它所做的是将一些计数器
N
设置为源代码中剩余的字符数。如果它能用掉那么多字符并使整个正则表达式匹配,它就会。否则,它将尝试
N-1
N-2
等,直到整个正则表达式匹配为止。我也认为在尝试这个的时候它是从左到右的;也就是说,由于
(.+)
是模式最左边的“部分”(对于“部分”的某些定义),它在该部分上循环,然后再尝试对右边的部分进行任何循环。因此,使
(.+)
贪婪比使模式的任何其他部分贪婪更重要;
(.+)
优先

在您的例子中,由于
(.+)
后面跟有一个可选部分,因此正则表达式匹配器首先尝试字符串的整个剩余部分——它成功了,因为字符串的剩余部分(为空)与可选子字符串完全匹配。这也解释了为什么如果子字符串不是可选的,那么它就不起作用——空的子字符串不再匹配


添加
使其成为一个“不情愿”(或“吝啬”)的量词,其作用方向相反。它首先看它是否能匹配0个字符,然后是1,2,…,而不是从N开始向下。因此,当它达到5时,匹配
“word”
,它发现字符串的其余部分与可选部分匹配,它就完成了,并给出了您期望的结果。

您好,感谢您的快速详细解释!它现在正在工作。然而,我还有一个问题要问,我已经把它作为问题的编辑。我之前没有问这个问题,因为我认为这与前面的问题类似。你知道为什么吗?因为正则表达式不是为解决世界上的所有问题而设计的。事实上,我想不出任何技术上的原因来解释为什么这种语言不能有一个“多组”来保存并返回重复捕获组的多个匹配项。我想对这种功能的需求并不多。
0: a, b, c, d
1: a
2: d