Java正则表达式模式匹配

时间:2015-09-02 02:15:55

标签: java regex

我想了解下面的Java正则表达式程序是如何工作的。我无法理解程序输出中的第二行

String line = "This order was placed for QT3000! OK?";
      String pattern = "(.*)(\\d+)(.*)";
Pattern r = Pattern.compile(pattern);

  // Now create matcher object.
  Matcher m = r.matcher(line);
  if (m.find( )) {
     System.out.println("Found value: " + m.group(0) );
     System.out.println("Found value: " + m.group(1) );
     System.out.println("Found value: " + m.group(2) );

这会产生这样的输出

Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0

我理解我们在字符串中搜索的模式是一个数字(\d+)的序列,其中包含(.*)之前和(.*)之后的任何内容。如果我在这里错了,请纠正我。

我知道m.group(0)返回整个字符串。我不明白输出的第二行。 找到的价值:此订单适用于QT300 。这里发生了什么?

2 个答案:

答案 0 :(得分:4)

它返回从第一个捕获组( ... )生成的匹配。由于默认情况下*greedy运算符,因此它匹配所有字符串中的最后一位数字。

打破它:

enter image description here

m.group(0)  →  Entire match     →  (.*)(\\d+)(.*) // This order was placed for QT3000! OK?
m.group(1)  →  Capture Group 1  →  (.*)           // This order was placed for QT300
m.group(2)  →  Capture Group 2  →  (\\d+)         // 0
m.group(3)  →  Capture Group 3  →  (.*)           // ! OK?

答案 1 :(得分:1)

这是因为正则表达式中的贪婪(尽可能多)和温顺(在需要时回馈)。 (Greedy... but Docile

  • 但是如果量化的令牌匹配了很多字符,而其他模式无法匹配,则引擎会回溯到量化的令牌并让它放弃它先前匹配的字符 - 一个字符或者一次一块,取决于量词是应用于单个字符还是应用于可以匹配多个字符块的子模式。放弃每个字符或块后,引擎再次尝试匹配模式的其余部分。我把这种贪婪量词的行为称为温顺。

因此,它很好地解释了你到达那里的情况。

  1. 0组:全部匹配
  2. 第一组:(。*)[贪婪]全部匹配,但会回溯到以下量化标记(\ d +)This order was placed for QT300
  3. 第二组:(\ d +)[贪心]至少一个数字0
  4. 3rd:(。*)[Greedy] ! OK?
  5. 要更好地理解如果将一个更改为无限制(\ d +)为零到无限制(\ d *),组1中的贪婪行为将全部采用。