我正在看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)