正则表达式第二篇
来源:互联网 发布:mac版qq群文件 编辑:程序博客网 时间:2024/05/01 11:28
1、捕获组(Capture Group)
捕获组就是把正则表达式中子表达式匹配的内容,保存到内存中以数字编号或手动命名的组里,以供后面引用。
表达式
说明
(Expression)
普通捕获组,将子表达式Expression匹配的内容保存到以数字编号的组里
(?<name> Expression)
命名捕获组,将子表达式Expression匹配的内容保存到以name命名的组里
普通捕获组(在不产生歧义的情况下,简称捕获组)是以数字进行编号的,编号规则是以“(”从左到右出现的顺序,从1开始进行编号。通常情况下,编号为0的组表示整个表达式匹配的内容。
命名捕获组可以通过捕获组名,而不是序号对捕获内容进行引用,提供了更便捷的引用方式,不用关注捕获组的序号,也不用担心表达式部分变更会导致引用错误的捕获组。
public static void group1() { Pattern p = Pattern.compile("\\d{3,5}[a-z]{2}");String s = "123aa-34345bb-234cc-00";Matcher m = p.matcher(s);while(m.find()) {System.out.print(m.group(0)+ " - "); /*整个表达式为第0组*/} } public static void group2() { //(\\d{3,5})第一组:([a-z]{2}):第二组 Pattern p = Pattern.compile("(\\d{3,5})([a-z]{2})"); String s = "123aa-34345bb-234cc-00";Matcher m = p.matcher(s);while(m.find()) {System.out.print(m.group(1) + " - ");//System.out.println(m.group(2));} }
2、非捕获组
一些表达式中,不得不使用( ),但又不需要保存( )中子表达式匹配的内容,这时可以用非捕获组来抵消使用( )带来的副作用。
表达式
说明
(?:Expression)
进行子表达式Expression的匹配,并将匹配内容保存到最终的整个表达式的区配结果中,但Expression匹配的内容不单独保存到一个组内
3、反向引用
捕获组匹配的内容,可以在正则表达式的外部程序中进行引用,也可以在表达式中进行引用,表达式中引用的方式就是反向引用。
反向引用通常用来查找重复的子串,或是限定某一子串成对出现。
表达式
说明
\1,\2
对序号为1和2的捕获组的反向引用
\k<name>
对命名为name的捕获组的反向引用
举例:
“(a|b)\1”在匹配“abaa”时,匹配成功,匹配到的结果是“aa”。“(a|b)”在尝试匹配时,虽然既可以匹配“a”,也可以匹配“b”,但是在进行反向引用时,对应()中匹配的内容已经是固定的了。
4、环视(Look Around)
环视只进行子表达式的匹配,匹配内容不计入最终的匹配结果,是零宽度的。
环视按照方向划分有顺序和逆序两种,按照是否匹配有肯定和否定两种,组合起来就有四种环视。环视相当于对所在位置加了一个附加条件。
表达式
说明
(?<=Expression)
逆序肯定环视,表示所在位置左侧能够匹配Expression
(?<!Expression)
逆序否定环视,表示所在位置左侧不能匹配Expression
(?=Expression)
顺序肯定环视,表示所在位置右侧能够匹配Expression
(?!Expression)
顺序否定环视,表示所在位置右侧不能匹配Expression
举例:
“(?<=Windows )\d+”在匹配“Windows 2003”时,匹配成功,匹配结果为“2003”。我们知道“\d+”表示匹配一个以上的数字,而“(?<=Windows )”相当于一个附加条件,表示所在位置左侧必须为“Windows ”,它所匹配的内容并不计入匹配结果。同样的正则在匹配“Office 2003”时,匹配失败,因为这里任意一串数字子串的左侧都不是“Windows ”。
“(?!1)\d+”在匹配“123”时,匹配成功,匹配的结果为“23”。“\d+”匹配一个以上数字,但是附加条件“(?!1)”要求所在位置右侧不能是“1”,所以匹配成功的位置是“2”前面的位置。
5、忽略优先和匹配优先
或者叫做正则表达式匹配的贪婪与非贪婪模式。
标准量词修饰的子表达式,在可匹配可不匹配的情况下,总会先尝试进行匹配,称这种方式为匹配优先,或者贪婪模式。此前介绍的一些量词,“{m}”、“{m,n}”、“{m,}”、“?”、“*”和“+”都是匹配优先的。
一些NFA正则引擎支持忽略优先量词,也就是在标准量词后加一个“?”,此时,在可匹配可不匹配的情况下,总会先忽略匹配,只有在由忽略优先量词修饰的子表达式,必须进行匹配才能使整个表达式匹配成功时,才会进行匹配,称这种方式为忽略优先,或者非贪婪模式。忽略优先量词包括“{m}?”、“{m,n}?”、“{m,}?”、“??”、“*?”和“+?”。
举例:
源字符串:<div>aaa</div><div>bbb</div>
正则表达式1:<div>.*</div> 匹配结果:<div>aaa</div><div>bbb</div>
正则表达式2:<div>.*?</div> 匹配结果:<div>aaa</div>
/*常用这个*/public static void fun1() { Pattern p = Pattern.compile(".{3,10}[0-9]"); /*3到10个字符后面跟着一位数字:没有问号:一次吃10个字符发现不匹配于是吐出一个字符再去匹配......*/String s = "aaaa5bbbb6";Matcher m = p.matcher(s);if(m.find())System.out.println(m.start() + "-" + m.end());else System.out.println("not match!"); }/*勉强模式*/ public static void fun2() { Pattern p = Pattern.compile(".{3,10}?[0-9]"); /*第一次吃3个字符看符合不?此时第四个表示数子,因此不符合,再吃进一位:此时符合*/String s = "aaaa5bbbb68";Matcher m = p.matcher(s);if(m.find())System.out.println(m.start() + "-" + m.end());else System.out.println("not match!"); } /*一般不用:占有模式*/ public static void fun3() { Pattern p = Pattern.compile(".{3,10}+[0-9]");/*一次吃10个字符并且不往外吐*/String s = "aaaa5bbbb6";Matcher m = p.matcher(s);if(m.find())System.out.println(m.start() + "-" + m.end());else System.out.println("not match!"); } public static void fun4() { Pattern p = Pattern.compile(".{3}"); String s = "444a66b";Matcher m = p.matcher(s);while(m.find()) {System.out.println(m.group());} } public static void fun5() { Pattern p = Pattern.compile(".{3}(?=a)"); /*(?=a):表示非捕获组(不捕获a):表示结束的字符是a*/String s = "444a66b";Matcher m = p.matcher(s);while(m.find()) {System.out.println(m.group());} } public static void fun6() { Pattern p = Pattern.compile("(?=a).{3}"); /*(?=a):表示非捕获组(不捕获a):表示以a打头后面三个字符,包挂a*/String s = "444a66b";Matcher m = p.matcher(s);while(m.find()) {System.out.println(m.group());} } public static void fun7() { Pattern p = Pattern.compile(".{3}(?=!a)"); String s = "444a66b";Matcher m = p.matcher(s);while(m.find()) {System.out.println(m.group());} } public static void fun8() { Pattern p = Pattern.compile(".{3}(?<=a)"); /*从后往前数还包含a的*/String s = "444a66b";Matcher m = p.matcher(s);while(m.find()) {System.out.println(m.group());} } /*向前引用*/ public static void fun9() { Pattern p = Pattern.compile("(\\d\\d)\\1");/*1:表示后面找到的结果必须和前面找到的一模一样*/String s = "1212";Matcher m = p.matcher(s);System.out.println(m.matches()); } /*向前引用*/ public static void fun10() { Pattern p = Pattern.compile("(\\d(\\d))\\2");/*(\\d(\\d)):这里是两个组:第二个组抓到的是2 后面的\\2:表示后面的要和第二个抓到数字一样*/String s = "122";Matcher m = p.matcher(s);System.out.println(m.matches()); } public static void fun11() { Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE); System.out.println("Java".matches("(?i)(java)")); /*(?i)非捕获组:是上面的简写*/ } public static void main(String[] args) { System.out.println("==================fun1();================================"); fun1(); System.out.println("==================fun2();================================"); fun2(); System.out.println("==================fun3();================================"); fun3(); System.out.println("==================fun4();================================"); fun4(); System.out.println("==================fun5();================================"); fun5(); System.out.println("==================fun6();================================"); fun6(); System.out.println("==================fun7();================================"); fun7(); System.out.println("==================fun8();================================"); fun8(); System.out.println("==================fun9();================================"); fun9(); System.out.println("==================fun10();================================"); fun10(); System.out.println("==================fun11();================================"); fun11();}
- 正则表达式第二篇
- 正则表达式第二章
- 第二十四天正则表达式
- 正则表达式【第二卷】
- 简单入门正则表达式 - 第二章 正则表达式应用范围
- 02关于正则表达式(第二则)常用正则表达式
- 正则表达式30分钟入门教程(第二版)
- 正则表达式30分钟入门教程(第二版)
- 正则表达式30分钟入门教程(第二版)
- 正则表达式30分钟入门教程(第二版)
- 正则表达式30分钟入门教程(第二版)
- 正则表达式30分钟入门教程(第二版)
- 正则表达式30分钟入门教程(第二版)
- 正则表达式30分钟入门教程(第二版)
- 正则表达式30分钟入门教程(第二版)
- 正则表达式30分钟入门教程(第二版)
- 正则表达式30分钟入门教程(第二版)
- 正则表达式30分钟入门教程(第二版)
- 哈尔滨理工大学-CPC23 2014-2-D-Alice and Bob
- java中反射类的加载和构造函数
- 数组、ArrayList和List三者的区别(C#)
- Android:滑动菜单栏(一)开源项目SlidingMenu的使用
- 阿里8.29,研发笔试题中的两个附加题
- 正则表达式第二篇
- Android.mk中设置PROPERTIES属性
- Android:滑动菜单栏(二)开源项目SlidingMenu的示例
- STL array的size方法(18)
- 链表的冒泡排序
- 二叉树基本操作的程序实现
- 单向链表操作
- C++之练习题41
- mysql日期选择函数