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中,您可以使用命名组更容易。
这完全没问题。
- 第一组(
m.group(0)
)总是捕获正则expression式覆盖的整个区域 。 在这种情况下,它是整个string。 - 正则expression式默认情况下是贪婪的,这意味着第一组尽可能地捕获而不违反正则expression式。
(.*)(\\d+)
(你的正则expression式的第一部分)包括...QT300
int第一组,第二个0
。 - 您可以通过将第一组非贪婪快速修复:将
(.*)
更改为(.*?)
。
有关贪婪与懒惰的更多信息,请查看本网站。
你的理解是正确的。 但是,如果我们走过:
-
(.*)
会吞下整个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发送整行。