zoukankan      html  css  js  c++  java
  • 正则表达式笔记

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

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

    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}+

  • 相关阅读:
    RESTful API 设计指南
    Lombok 安装配置及使用方法
    Python——urllib函数网络文件获取
    C与C++面试易出知识点
    编程一年
    Java练习1
    大整数求和
    PHP数组知识点整理
    CSS——NO.10(设置技巧)
    CSS——NO.9(颜色值和长度值)
  • 原文地址:https://www.cnblogs.com/licorice/p/11101735.html
Copyright © 2011-2022 走看看