Java正则expression式捕获组

我想了解这个代码块。 第一个,我们在expression什么?

我的理解是任何字符(0或更多*),后面跟着0到9之间的任何数字(一个或多个+),后面是任何字符(0或更多次*)。

当这个被执行时,结果是:

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

有人可以和我一起经历这个吗?

使用捕获组有什么优势?

 import java.util.regex.Matcher; import java.util.regex.Pattern; public class RegexTut3 { public static void main(String args[]) { 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); 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)); } else { System.out.println("NO MATCH"); } } } 

你遇到的问题是量词的types。 你在第一组中使用了一个贪婪的量词(索引1 – 索引0代表整个Pattern ),这意味着它将尽可能匹配(因为它是任何字符,它将匹配那里的字符数量是为了满足下一组的条件)。

总之,只要下一个组\\d+可以匹配任何东西(在这个例子中是最后一个数字),您的第一组.*匹配任何东西。

按照第三组,它会匹配最后一位数字后的任何内容。

如果你把它改成第一组中的一个不情愿的量词,你会得到我期望的结果,也就是3000部分。

注意第一组中的问号

 String line = "This order was placed for QT3000! OK?"; Pattern pattern = Pattern.compile("(.*?)(\\d+)(.*)"); Matcher matcher = pattern.matcher(line); while (matcher.find()) { System.out.println("group 1: " + matcher.group(1)); System.out.println("group 2: " + matcher.group(2)); System.out.println("group 3: " + matcher.group(3)); } 

输出:

 group 1: This order was placed for QT group 2: 3000 group 3: ! OK? 

有关Java Pattern更多信息。

最后,捕获组由圆括号分隔,并且一旦您的Pattern与input相匹配,就提供了一种非常有用的方法来使用反向引用(除其他外)。

在Java 6组中,只能按照它们的顺序来引用(注意嵌套组和sorting的细微差别)。

在Java 7中,您可以使用命名组更容易。

这完全没问题。

  1. 第一组( m.group(0) )总是捕获正则expression式覆盖的整个区域 。 在这种情况下,它是整个string。
  2. 正则expression式默认情况下是贪婪的,这意味着第一组尽可能地捕获而不违反正则expression式。 (.*)(\\d+) (你的正则expression式的第一部分)包括...QT300 int第一组,第二个0
  3. 您可以通过将第一组非贪婪快速修复:将(.*)更改为(.*?)

有关贪婪与懒惰的更多信息,请查看本网站。

你的理解是正确的。 但是,如果我们走过:

  • (.*)会吞下整个string;
  • 它将需要返回字符,以便(\\d+)得到满足(这就是为什么0被捕获,而不是3000 );
  • 最后(.*)将会捕获其余的。

不过,我不确定作者的原意是什么。

从文档:

 Capturing groups</a> are indexed from left * to right, starting at one. Group zero denotes the entire pattern, so * the expression m.group(0) is equivalent to m.group(). 

所以捕获组0发送整行。