java正则表达式——Greedy、Reluctant和Possessive
测试1:
1 package jichu; 2 3 import java.util.regex.Matcher; 4 import java.util.regex.Pattern; 5 6 public class MainClass { 7 public static void main(String[] args) { 8 Matcher m1 = Pattern.compile("\\w+").matcher("ababa");// 贪婪的 9 Matcher m2 = Pattern.compile("\\w+?").matcher("ababa");// 勉强的 10 Matcher m3 = Pattern.compile("\\w++").matcher("ababa");// 独占的 11 System.out.println(piPei(m1)); 12 System.out.println(piPei(m2)); 13 System.out.println(piPei(m3)); 14 } 15 16 public static String piPei(Matcher m) { 17 StringBuffer s = new StringBuffer(); 18 int i = 0; 19 while (m.find()) { 20 s.append("{匹配子串" + ++i + ":" + m.group() + ";"); 21 s.append("开始位置:" + m.start() + ";"); 22 s.append("结束位置:" + m.end() + ";}"); 23 } 24 if (s.length() == 0) { 25 s.append("没有匹配到!"); 26 } 27 s.insert(0, "(模式" + m.pattern().pattern() + "):"); 28 return s.toString(); 29 } 30 }
打印:
1 (模式\w+):{匹配子串1:ababa;开始位置:0;结束位置:5;} 2 (模式\w+?):{匹配子串1:a;开始位置:0;结束位置:1;}{匹配子串2:b;开始位置:1;结束位置:2;}{匹配子串3:a;开始位置:2;结束位置:3;}{匹配子串4:b;开始位置:3;结束位置:4;}{匹配子串5:a;开始位置:4;结束位置:5;} 3 (模式\w++):{匹配子串1:ababa;开始位置:0;结束位置:5;}
从测试1中可知:
1、对于贪婪的,会一次性匹配所有的字符;
2、对于勉强的,会从左到右一个一个的匹配;
3、对于独占的,与贪婪的一样也是一次性匹配所有的字符;
测试2:(在测试1的基础上修改main方法)
1 public static void main(String[] args) { 2 Matcher m1 = Pattern.compile("\\w+b").matcher("ababa");// 贪婪的 3 Matcher m2 = Pattern.compile("\\w+?b").matcher("ababa");// 勉强的 4 Matcher m3 = Pattern.compile("\\w++b").matcher("ababa");// 独占的 5 System.out.println(piPei(m1)); 6 System.out.println(piPei(m2)); 7 System.out.println(piPei(m3)); 8 }
打印:
1 (模式\w+b):{匹配子串1:abab;开始位置:0;结束位置:4;} 2 (模式\w+?b):{匹配子串1:ab;开始位置:0;结束位置:2;}{匹配子串2:ab;开始位置:2;结束位置:4;} 3 (模式\w++b):没有匹配到!
从测试1、2中可知:
1、对于贪婪的,'\w+'已经一次性匹配了所有的字符;当模式后加'b'后,此时不匹配,然后回溯1个字符,匹配成功。
2、对于勉强的,从左到右匹配,匹配出两个子串。
3、对于独占的,'\w++'已经一次性匹配了所有的字符;当模式后加'b'后,此时不匹配,与贪婪的不一样的是它不会回溯,所以匹配失败。
总结
1、Greedy数量词为“贪婪的”,如名字一样,多吃多占,它会尽可能多的匹配字符,会回溯。
2、Reluctant数量词为“勉强的”,奉行够用主义,它会尽可能少的匹配字符。
3、Possessive数量词为“独占的”,它会如Greedy一样尽可能多的匹配字符,但是它不会回溯。
世事如棋,乾坤莫测,笑尽英雄啊!