码迷,mamicode.com
首页 > 其他好文 > 详细

正则数量词及非捕获

时间:2015-04-10 18:18:16      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

一、数量词:Greedy Reluctant Possessive                

        String str = "abcdabg";
		
		// ①Greedy
		// output:abcdab 
		Pattern pattern1 = Pattern.compile(".*ab");
		Matcher matcher1 = pattern1.matcher(str);
		while (matcher1.find()) {
			System.out.print(matcher1.group() + " ");
		}
		System.out.println();
		
		// ②Reluctant
		// output:ab cdab 
		Pattern pattern2 = Pattern.compile(".*?ab");
		Matcher matcher2 = pattern2.matcher(str);
		while (matcher2.find()) {
			System.out.print(matcher2.group() + " ");
		}
		System.out.println();
		
		// ③Possessive 
		// no output
		Pattern pattern3 = Pattern.compile(".*+ab");
		Matcher matcher3 = pattern3.matcher(str);
		while (matcher3.find()) {
			System.out.println(matcher3.group());
		}
1.Greedy:贪婪,表示匹配的时候先匹配整个字符串,如果匹配成功,则终止,如果不匹配,再从右向左一个一个吐出来(因为他太贪婪了),过程如下:

模式:.*ab,要匹配的字符abcdabg,注意是.*来匹配

1.先匹配abcdabg,不成功

2.匹配abcdab,还是不成功

3.匹配abcda,还是不成功

4.匹配abcd,匹配成功,后面刚好是ab

所以最终输出的是abcdab

2.Reluctant 勉强,匹配过程是从左到右,先从最左边吃掉一个字符,不匹配的话接着吃点(我很不愿意,所以很勉强),一直到匹配的,但这时不会退出,而是继续匹配,过程如下:

模式:.*?ab,要匹配的字符abcdabg,注意是.*来匹配

1.先匹配a,不成功

2.匹配ab,成功,继续匹配

3.匹配c,不成功

4.匹配cd,成功,后面刚好是ab

5.匹配cda,不成功,继续匹配到末尾

所以最终输出的是ab cdab

3.Possessive 侵占,表示我一次性匹配整个字符串,而且只匹配一次,要么成功,要么不成功 

模式:.*+ab,要匹配的字符abcdabg,注意是.*来匹配

1.直接匹配abcdabg,.*直接吃掉整个字符串了,没有字符来匹配后面的ab了,当然是不匹配了,然后就终止了,所以没有任何输出

二、捕获与非捕获

这2个都是用()来包起来的,看下面的例子就知道2者的区别了

String str = "industries";
 
 // ①捕获
 Pattern pattern1 = Pattern.compile("industr(y|ies)");
 Matcher matcher1 = pattern1.matcher(str);
 while (matcher1.find()) {
 System.out.println(matcher1.group(0) + "+++" + matcher1.group(1));
 }
 
 // ②非捕获
 Pattern pattern2 = Pattern.compile("industr(?:y|ies)");
 Matcher matcher2 = pattern2.matcher(str);
 
 while (matcher2.find()) {
 System.out.println(matcher1.group(0) + "+++" + matcher2.group(1));
 }
结果为:

industries+++ies
Exception in thread "main" java.lang.IllegalStateException: No match found
 at java.util.regex.Matcher.group(Matcher.java:468)
 at com.reg.TestAt.main(TestAt.java:47)

对于捕获的,()会被当做一个分组,所以还有一个小标为1的组

但是对于非捕获,是没有组的,所以就出现下标异常了

非捕获

直接看下面的例子比较容易理解:

System.out.println("---------(?=X)---------");
		// lookahead 向后看
		// (?=X) X,通过零宽度的正 lookahead 
		/*表达式"a(?=b)c"不能匹配"abc",也不能匹配"ac"、"ab"。而且不能匹配任何字符串。因为其预测匹配a的位置后,应该是b,但是,又要求a之后是c。
		表达式"a(?=b)bc"是可以匹配"abc"的,但是不能匹配"ab"和"ac"。*/
		Pattern p1 = Pattern.compile("a(?=c)");
		System.out.println(p1.matcher("ac").matches());// 这种是不包含的,所以为false,对比下面的
		Matcher matcher1 = p1.matcher("ac");
		while(matcher1.find()) {
			System.out.println(matcher1.group());// 结果为a
		}
		
		System.out.println("---------(?>X)---------");
		Pattern p11 = Pattern.compile("a(?>c)");
		System.out.println(p11.matcher("ac").matches());// 这种是包含的,所以为true,对比上面的
		Matcher matcher11 = p11.matcher("ac");
		while(matcher11.find()) {
			System.out.println(matcher11.group());
		}
		
		System.out.println("---------(?!X)---------");
		// (?!X) X,通过零宽度的负 lookahead 
		// a(?!c)b 表示a后面不能是c,且是b,所以为true
		Pattern p2 = Pattern.compile("a(?!c)b");// a(?!b)b
		System.out.println(p2.matcher("ab").matches());
		
		System.out.println("---------(?<=X)---------");
		// lookbehind 向前看
		// (?<=X) X,通过零宽度的正 lookbehind 
		// a(?<=a)c 表示c前面必须是a
		Pattern p3 = Pattern.compile("a(?<=a)c");
		System.out.println(p3.matcher("ac").matches());
		
		System.out.println("---------(?<!X)---------");
		// (?<!X) X,通过零宽度的负 lookbehind 
		// b(?<!a)c 表示c前面不能是a,且必须是b
		Pattern p4 = Pattern.compile("(?<!a)c");
		System.out.println(p4.matcher("c").matches());
		Matcher matcher4 = p4.matcher("ecb");
		while(matcher4.find()) {
			System.out.println(matcher4.group());
		}
		
		System.out.println("---------(?idmsux-idmsux)---------");
		// 一共有:i d m s u x 这些个值,其实对应一些常量,见下面
		Pattern p12 = Pattern.compile("(?i)abc");// i表示CASE_INSENSITIVE,不区分大小写;(?-i)表示否定,即区分大小写
		System.out.println(p12.matcher("aBc").matches());
		Matcher matcher12 = p12.matcher("aBc");
		while(matcher12.find()) {
			System.out.println(matcher12.group());
		}
		
		// 这种方式和上面的效果一样,看你喜欢哪一种
		Pattern p13 = Pattern.compile("abc", Pattern.CASE_INSENSITIVE);
		System.out.println(p13.matcher("aBc").matches());
		Matcher matcher13 = p13.matcher("aBc");
		while(matcher13.find()) {
			System.out.println(matcher13.group());
		}
		
		System.out.println("---------(?idmsux-idmsux:X)---------");
		Pattern p14 = Pattern.compile("(?i:efg)ab");
		System.out.println(p14.matcher("eFGabc").matches());
		Matcher matcher14 = p14.matcher("eFGabc");
		while(matcher14.find()) {
			System.out.println(matcher14.group());
		}
		
		System.out.println("--------- Appendix ---------");
		// (?:X) X,作为非捕获组 
		// (?>X) X,作为独立的非捕获组 
		// 指针会移动(是包含在内的),注意和(?=X)的区别
		Pattern p5 = Pattern.compile("a(?:b)"); 
		System.out.println(p5.matcher("ab").matches());
		Pattern p9 = Pattern.compile("a(?>b)");
		System.out.println(p9.matcher("ab").matches());
上面例子都理解了,非捕获基本也就理解了,不过实际中用的也不多


正则数量词及非捕获

标签:

原文地址:http://my.oschina.net/dxqr/blog/398567

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!