正则表达式笔记

何为正则表达式?正则表达式在我看来就是一个特定的字符串规则。

在工作中,字符串操作是非常频繁,正则表达式的用途我总结有以下几点:

1、判断字符串是否满足正则表达式(也就说一个字符串是否满足我们定义的规则)

如:定义一个正则表达式  “^a[a-z]*e$”  表示一个以a开头,以e结尾的任意长度的一串字母

可以用这个正则表达式来检测其它输入的字符串是否满足这个规则。

2、提取输入字符串中的数据

如:定义一个表达式  "(d{4})-(d{1,2})-(d{1,2})", 表示规则为:  四个数字-一到两个数字-一到两个数字

可以用来提取 “yyyy-MM-dd”格式日期字符串中yyyy ,MM ,dd等数据

正则表达中的子模式的应用

在使用子模式过程中,常见两种写法是:1 和 $1。 
(1) 1 是在正则表达式本身中引用分组1的内容,如: 
我们要匹配111这样的连续出现3此的数字,我们可以写出正则:(d)11(d)匹配到第一个1,后面再引用这个匹配内容,得到111。 
(2) $1 是在替换中调用分组的内容(在正则表达式外面用,多用于使用正则表达式来替换数据),如: 

String str = "abc def";
String replaceFirst = str.replaceFirst("(\w+)\s+(\w+)", "$2 $1");  将字符串前面的部分和后面的部分位置兑换

在java中使用模式匹配取数据时,字符串中会有多个部分匹配,可以通过循环依次取得所有的数据;java通过group取数据有个坑,在取数据之前,Matcher对象必须要先查找一次,先调用find方法

 Pattern p6 = Pattern.compile("(?<=\s)\d+(?=\s)");
     Matcher matcher6 = p6.matcher("ht 1 3 2 5 as f d 6 ");
     while(matcher6.find()) {
         System.out.println(matcher6.group());
     }

非捕获组(?:)主要用来做数据分解,不会捕获匹配的数据,如下就会只有一个捕获组,捕获的域名

 Pattern p5 = Pattern.compile("(?:http|ftp|svn)://([^/]+)");
     Matcher matcher5 = p5.matcher("http://192.168.0.1/689");
     
     if(matcher5.find()) {
         System.out.println(matcher5.group(1));
     }   
 

模式修饰符

模式修饰符在许多程序语言中都支持的,比如最常见的是i,不区分大小写,如javascript里的/[a-z0-9]/i,表示匹配字母数字,不区分大小写。

在java中需要在编译正则的时候去指定模式。

  Pattern p3 = Pattern.compile("a*?b",Pattern.CASE_INSENSITIVE);
     Matcher matcher3 = p3.matcher("aaBaB");
     matcher3.find();
     System.out.println(matcher3.group());

或者使用表达式:

模式修饰符:(?mods-mods:)允许出现的模式:x d s m i u

模式修饰范围:(?mods-mods:...)

 

环视,在不同的地方又称之为零宽断言,简称断言。 

就是先从全局环顾一遍正则,(然后断定结果,)再做进一步匹配处理。环视的分组不占位置,book(?=s)匹配books中的book; 

环视主要有以下4个用法: 
(?<=exp) 匹配前面是exp的数据 
(?<!exp) 匹配前面不是exp的数据 
(?=exp) 匹配后面是exp的数据 
(?!exp) 匹配后面不是exp的数据

   Pattern p2 = Pattern.compile("(?<=\s)\d+(?=\s)");
      Matcher matcher2 = p2.matcher("I'm singing 3 2 dancing"); 
      matcher2.find();
     System.out.println(matcher2.group(0));
     

环视的特点,环视部分是不占宽度的,所以有零宽断言的叫法。 
所谓不占宽度,可以分成两部分理解: 
1、环视的匹配结果不纳入数据结果 
2、环视它匹配过的地方,下次还能用它继续匹配。

如上得到的分组结果是 "3" 而不是“ 3 ”(3旁边有空白符) ,

正则表达式性能问题:

1.使用字符组代替分支条件

如 [a-d] 替换(a|b|c|d)

2.优先最左匹配

如用分支条件(你好|hi|hello)预测匹配量大的词放在最左边,NFA引擎来说,因为引擎一旦找到匹配结果就会停下来,就不用回溯

3. 标准量词匹配有限

若用量词约束某个表达式,那么在匹配成功前,进行的尝试次数有下限和上限。

4.谨慎用点号元字符,尽可能不用星号和加号这样的任意量词

只要能确定范围(eg.“w”),就不要用点号;只要能够预测重复次数,就不要用量词。

捕获型括号:(...)  1 2...

仅分组的括号:(?:...)

固化分组:(?>...)    匹配规则与普通括号一样,唯一的区别就是,当此部分表达式匹配完毕,开始匹配括号外面的部分时,括号内的所有备用状态都会被放弃。也就是不会获取分组,不能在正则中反向引用

多选结构:|

匹配优先量词:* + ? {n} {m,n} {m,}

忽略优先量词:*? +? ?? {n}? {n,}? {m,n}?

占有优先量词:*+ ++ ?+ {n}+ {n,}+ {m,n}+

原文地址:https://www.cnblogs.com/licorice/p/11101735.html