为什么在`(。+?)之后添加空格可以完全改变结果

时间:2016-03-03 02:07:12

标签: java regex regex-group

我正在尝试在更大的字符串中找到一个较小的字符串String patternString1 = "(John) (.+?)";。较小的字符串由两组组成,即(John) (.+?)。但是,我通过在(.+?)之后添加一个空格来获得完全不同的结果。

对于String patternString1 = "(John) (.+?)";,(即没有空格),结果是

found: John w
found: John D
found: John W

对于String patternString1 = "(John) (.+?) ";,(即带空格),结果为

found: John writes
found: John Doe
found: John Wayne

为什么空间可以对结果产生如此大的影响?

String text
        = "John writes about this, and John Doe writes about that,"
        + " and John Wayne writes about everything.";

String patternString1 = "(John) (.+?)";
Pattern pattern = Pattern.compile(patternString1);
Matcher matcher = pattern.matcher(text);

while (matcher.find()) {
    System.out.println("found: " + matcher.group(1) + " " + matcher.group(2));
}

2 个答案:

答案 0 :(得分:2)

.+?量词是不情愿的(或"懒惰")。这意味着它将匹配其量化一次或多次的子模式,只需几次返回有效匹配

您拥有(John) (.+?)模式,并尝试在John writes about this中找到匹配项。正则表达式引擎找到John,将其放入第1组内存缓冲区,找到空格,匹配它,然后在w中找到writesw已匹配,因此符合一个或多个的要求。由于匹配已经有效,因此会返回。得到John w

现在,您在(.+?)之后添加一个空格。如前所述,John被匹配并捕获到组1中,空间与模式中的空间匹配(再次,如前所述),然后执行.+? - 在{{1}之前找到空位置}}。它匹配此位置并继续匹配空间。该位置没有空间,因为writes。正则表达式引擎返回w并消耗.+?。检查w是否是空格 - 不,不是。引擎以这种方式检查字符串直到第一个匹配空间,并在r之后立即找到它。因此,writes的有效匹配为(John) (.+?)

答案 1 :(得分:1)

好吧,如果你包含尾随空格,你也要求模式匹配那个空格。

John w不再匹配,因为它不以空格结尾。

必须将其扩展为John writes(请注意,匹配包括末尾的空格)。