正则数量词及非捕获

前端之家收集整理的这篇文章主要介绍了正则数量词及非捕获前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

一、数量词:GreedyReluctantPossessive

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,成功,Arial;font-size:12px;line-height:18px;background-color:#F6F6F6;">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());
上面例子都理解了,非捕获基本也就理解了,不过实际中用的也不多

猜你在找的正则表达式相关文章