正则数量词及非捕获
一、数量词: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());上面例子都理解了,非捕获基本也就理解了,不过实际中用的也不多 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ruby – 如何从Gemfile安装gem?
- 对Ajax的支持——深入浅出学Spring Web MVC
- cocos-js 使用clipingnode 将正方形图片裁切成圆形图片
- 如何以编程方式获取OS X上给定PID的打开文件描述符列表?
- 我们可以测试符合相同协议的对象在swift中是否完全相同而不
- 重磅:前端 MVVM 与 FRP 的升阶实践 —— ReRest 可视化编程
- swift – 将URL转换为String并再次返回
- c# – 使用自定义查询在ID列表中选择其ID存在的项目
- VBA粘贴Excel活动工作表中每一嵌入式图表到一个新的PowerPo
- PostgreSQL学习笔记---如何包含有单引号的字符串