Java正则表达式匹配器找不到所有可能的匹配项

Cyp*_*her 3 java regex

我正在看TutorialsPoint的代码,从那以后一直困扰着我......看看这段代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches
{
    public static void main( String args[] ){

      // String to be scanned to find the pattern.
      String line = "This order was placed for QT3000! OK?";
      String pattern = "(.*)(\\d+)(.*)";

      // Create a Pattern object
      Pattern r = Pattern.compile(pattern);

      // Now create matcher object.
      Matcher m = r.matcher(line);
      while(m.find( )) {
         System.out.println("Found value: " + m.group(1));
         System.out.println("Found value: " + m.group(2));
         System.out.println("Found value: " + m.group(3));
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

此代码成功打印:

Found value: This was placed for QT300 
Found value: 0
Found value: ! OK?
Run Code Online (Sandbox Code Playgroud)

但根据正则表达式"(.*)(\\d+)(.*)",为什么不返回其他可能的结果,例如:

Found value: This was placed for QT30 
Found value: 00
Found value: ! OK?
Run Code Online (Sandbox Code Playgroud)

要么

Found value: This was placed for QT 
Found value: 3000
Found value: ! OK?
Run Code Online (Sandbox Code Playgroud)

如果这段代码不适合这样做,那么如何编写一个可以找到所有可能匹配的代码呢?

Avi*_*Raj 5

这是因为的贪婪*,有自带的回溯.

字符串:

This order was placed for QT3000! OK?
Run Code Online (Sandbox Code Playgroud)

正则表达式:

(.*)(\\d+)(.*)
Run Code Online (Sandbox Code Playgroud)

我们都知道这.*是贪婪的,并且尽可能地匹配所有角色.因此,第一个.*匹配所有字符直到最后一个字符,?然后它按顺序回溯以提供匹配.我们的正则表达式中的下一个模式是\d+,所以它回溯到一个数字.找到一个数字后,\d+匹配该数字,因为此处满足条件(\d+匹配一个或多个数字).现在,第一个(.*)捕获This order was placed for QT300和以下(\\d+)捕获0位于!符号之前的数字.

现在,下一个模式(.*)捕获所有剩余的字符!<space>OK?. m.group(1)指的是在组索引1中存在的字符并且m.group(2)引用索引2,就像它继续进行一样.

请在此处查看演示.

获得所需的输出.

String line = "This order was placed for QT3000! OK?";
  String pattern = "(.*)(\\d{2})(.*)";

  // Create a Pattern object
  Pattern r = Pattern.compile(pattern);

  // Now create matcher object.
  Matcher m = r.matcher(line);
  while(m.find( )) {
     System.out.println("Found value: " + m.group(1));
     System.out.println("Found value: " + m.group(2));
     System.out.println("Found value: " + m.group(3));
  }
Run Code Online (Sandbox Code Playgroud)

输出:

Found value: This order was placed for QT30
Found value: 00
Found value: ! OK?
Run Code Online (Sandbox Code Playgroud)

(.*)(\\d{2}),按顺序回溯最多两位数以提供匹配.

将您的模式更改为此,

String pattern = "(.*?)(\\d+)(.*)";
Run Code Online (Sandbox Code Playgroud)

为了获得输出,

Found value: This order was placed for QT
Found value: 3000
Found value: ! OK?
Run Code Online (Sandbox Code Playgroud)

?* 力量之后*做了一场非贪婪的比赛.

使用额外的捕获组来获取单个程序的输出.

String line = "This order was placed for QT3000! OK?";
String pattern = "((.*?)(\\d{2}))(?:(\\d{2})(.*))";
Pattern r = Pattern.compile(pattern);
      Matcher m = r.matcher(line);
      while(m.find( )) {
         System.out.println("Found value: " + m.group(1));
         System.out.println("Found value: " + m.group(4));
         System.out.println("Found value: " + m.group(5));
         System.out.println("Found value: " + m.group(2));
         System.out.println("Found value: " + m.group(3) + m.group(4));
         System.out.println("Found value: " + m.group(5));
     }
Run Code Online (Sandbox Code Playgroud)

输出:

Found value: This order was placed for QT30
Found value: 00
Found value: ! OK?
Found value: This order was placed for QT
Found value: 3000
Found value: ! OK?
Run Code Online (Sandbox Code Playgroud)