有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java正则表达式中的“(.*)”、“(.*)+”、“.+)*”有一个奇怪的问题

为了重新产生最近一个问题-Why does (.*)* make two matches and select nothing in group $1?中所述的问题,我尝试了*+在括号内和括号外的各种组合,结果出乎意料

我本希望得到的结果与该问题中已接受的答案中所解释的结果相同,并且在另一个重复的问题中也是如此,标记在Perl-Why doesn't the .* consume the entire string in this Perl regex?下。但它的行为方式不同

为了简单起见,以下是我尝试的代码:-

String str = "input";
String[] patterns = { "(.*)*", "(.*)+", "(.+)*", "(.+)+" };

for (String pattern: patterns) {
    Matcher matcher = Pattern.compile(pattern).matcher(str);

    while (matcher.find()) {
        System.out.print("'" + matcher.group(1) + "' : '" + matcher.start() + "'" + "\t");
    }

    System.out.println();
}

这是我得到的所有4个组合的输出:-

'' : '0'    '' : '5'            // For `(.*)*`
'' : '0'    '' : '5'            // For `(.*)+`  
'input' : '0'   'null' : '5'    // For `(.+)*`
'input' : '0'                   // For `(.+)+`

现在,我不明白的是,为什么在1st2nd输出中,我没有得到matcher.find()的整个字符串作为first result。我的意思是,理想情况下,在第一种情况下,.*应该首先捕获整个字符串,然后在最后捕获empty string。现在,虽然它给出了第二场比赛的预期结果,但它在1st match中的表现并不好

而且,在第二种情况下,我甚至不应该得到第二个匹配,因为我在括号外有一个+量词

我的预期产出是:-

'input' : '0'   '' : '5'  // For 1st
'input' : '0'    // For 2nd

另外,在3rd输出中,为什么我将null作为第二个匹配而不是empty string呢?前三个组合的第二个匹配不应该相同吗

第四个输出符合预期。所以,毫无疑问


共 (1) 个答案

  1. # 1 楼答案

    你看到了与你所链接的问题相同的现象的影响:

    对于(.*)*

    • 第一个matcher.start()0,因为这是匹配("input")的开始
    • 第一个matcher.group(1)"",因为重复的(.*)已经用空字符串覆盖了捕获的"input"(但是matcher.group(0)确实包含input"
    • 第二个matcher.start()5,因为在第一次成功匹配之后,正则表达式引擎就在那里
    • 第二个matcher.group(1)(以及matcher.group(0))是"",因为这是字符串末尾要匹配的全部内容

    对于(.*)+来说也是一样的。毕竟,空字符串可以重复任意多次,但仍然是空字符串

    对于(.+)*您会得到null,因为当第二次匹配成功时(长度为1的字符串的零次重复匹配空字符串),捕获括号无法捕获任何内容,因此其内容是null(如未定义,而不是空字符串)