2015-09-02 217 views
1

我想了解下面的Java正则表达式程序是如何工作的。我无法理解在程序的输出的第二行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。这里发生了什么?

回答

3

它返回从第一个捕获组(...)产生的匹配。并且由于默认情况下*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? 
+0

感谢您的回复。我能够理解这是如何与您的解释 –

1

这是由于双方的贪婪(尽可能多)和温顺(必要时给予回复),从正则表达式。 (Greedy... but Docile

  • 但如果定量令牌匹配这么多字,该模式的其余部分不能匹配,则发动机将回溯到量化令牌并使其放弃它匹配的字符前面一字符或块,具体取决于量词是应用于单个字符还是应用于可匹配多个字符块的子模式。放弃每个角色或大块后,引擎再次尝试匹配模式的其余部分。我把这种贪婪的量词称为温顺的行为。

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

  1. 0组:匹配所有
  2. 第一组:[贪婪]匹配所有但将回溯到下面的量化令牌(\ d +)This order was placed for QT300
  3. 第二组(*):(\ d +)[贪婪]至少一位0
  4. 3:(。*)[贪婪] ! OK?

如果你改变了一个无限(\ d +),以零到无限(\ d *)为了更好地理解,来自第1组的贪婪行为将采取一切。

+0

感谢您的答复。我能够理解这是如何工作的,你的解释 –

+1

至少标记为答案/ upvote .... – bLaXjack