我正在看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)
如果这段代码不适合这样做,那么如何编写一个可以找到所有可能匹配的代码呢?
字符串:
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)