正则表达式入门只需10分钟

一、正则表达式里面的字符串与数字

       1、\w或者.可以匹配任意字符串;

       2、使用\d匹配0-9中的任意一个数字

       3、使用\b匹配单词的分隔符

       4、使用字符串集合[]代表批次[]中的任何一个元素,举例如下:

              [abcd]代表匹配a、b、c、d四个字符中的任意一个

            需要注意的是有3个固定写法:

              [a-z]代表23个小写字符;

              [A-Z]代表23个大写字符;

              [0-9]代表10个一位数字;

            他们3个能混合使用也能和其他字符串混合使用,举例如下:

              比如[a-zA-Z0-9$]匹配24个大小写字母和10个数字和$这个特殊符号中的任意一个

二、正则表达式里面的重复次数控制

       1、使用+代表重复1次或者1次以上;

       2、使用*代表重复任意次数;

       3、使用?代表重复0次或者1次;

       4、使用重复区间{}代表具体重复的次数,使用举例如下:

              {3,8}重复3到8次

              {3,}重复3次以上

三、正则表达式里面的贪婪模式与非贪婪模式

       先设想有如下正则表达式:

              <[hH][0-9]>.*</[hH[0-9]]>

       匹配如下字符串:

              <h1>这是大标题</h1><h2>这是副标题</h2>

       请猜想会返回几条匹配结果?

              答案是一条,.*匹配任意内容,*和+好默认都是贪婪模式,会尽可能多的去匹配内容了,我们预想的是</[hH[0-9]]>匹配到第一个</h1>的时候就返回一条匹配结果,但是因为.*同样能匹配</h1>因此,这个表达式的一条匹配结果匹配了最多的内容才返回,这是一条非常重要的逻辑;

       在使用中可以在+和*号后面加上?好来开启非贪婪匹配,写法如下:<[hH][0-9]>.*?</[hH[0-9]]>

       该表达式匹配上面的字符串,会返回两条匹配,使用?好之后,每次匹配将尽可能匹配少的内容,当</h1>被</[hH[0-9]]>匹配到的时候就马上返回一次匹配。

四、正则表达式里面的子表达式

       之上的知识都是针对单个字符串的匹配,比如ab{3}只能匹配abbb这种内容,那如果我想要匹配ababab这种内容,应该怎么办?

       之前的之上显然满足不了我们的需求,这里就需要使用子表达式()来实现我们的需求;

       通俗的讲,子表达式就是将一个正则表达式里面的几个字符串作为一个整体来重复,它主要有两个功能,都非常重要

              1、将几个字符串作为整体来重复;

                     举例:a(ab){3}将会匹配aababab字符串

              2、能在每条匹配的内容里面提取子内容;

                     举例:想提取html内容:<h1>这是大标题</h1>中的文本内容,应该怎么办?

                     使用<[hH][0-9]>(.*?)</[hH[0-9]]>可以将“这是大标题”这段文本提取出来,具体的使用需要跟编程语言联合起来,在第七章里面详细介绍,这个用法非常核心,以我为例,在Java中的使用十之八九都需要使用子表达式的这个特性。

五、正则表达式里面的回溯引用

       试想有如下的html文本:<h1>这是大标题</h1><h2>这是副标题</h3>,我只想匹配其中正确的html内容,应该怎么办?

       之前的知识显然无法解决此需求!

       这里需要使用到回溯引用(),这是正则表达式的特性,将()号里面匹配的内容当成一个变量保存起来,使用的时候用\n这种格式来调用该变量,\1代表第一个变量,\2代表第二个变量,以此类推;举例如下:

              <([Hh][0-9])>.*?</\1>匹配上述的html文本,这会返回<h1>这是大标题</h1>

六、正则表达式里面的向前查找、向后查找

       回到第四章节里面的疑问,我想只匹配<h1>这是大标题</h1>中的文本内容,应该怎么办?

       使用之前的子表达式可以使用此需求,但是稍显复杂,使用向前向后查找,可以更为简答的实现此需求;

       向前向后查找的意思是,判断前面/后面是否包含子表达式里面的内容,如果包含,才能匹配上,否则不能匹配上,相当于是做条件判断,对于表达式匹配中的文本,只返回它之前\之后的内容,而不返回自身;任意一个子表达式都可以在它的前面加上?=或者?<=来实现向前向后查找,举例如下:

              1、向前查找(?=);

                     使用正则.*?(?=:)匹配文本aaaaaaaaaaaa:bbbbbbbbbbbb,本来应该返回aaaaaaaaaaaa:,但是由于对子表达式(:)使用了向前查找,所以将不会再返回:本身,只返回aaaaaaaaaaaa

              2、向后查找(?<=);

                     使用正则(?<=:).*匹配文本aaaaaaaaaaaa:bbbbbbbbbbbb,本来应该返回:bbbbbbbbbbbb,但是由于对子表达式(:)使用了向前查找,所以将不会再返回:本身,只返回它之后的内容bbbbbbbbbbbb

       现在对于我们只匹配<h1>这是大标题</h1>中的文本内容的这个需求,可以用向前向后查找实现了,具体如下:

              (?<=<[Hh][0-9]>).*?(?=</[Hh][0-9]>)

七、Java中正则表达式的使用总结

       1、使用子表达式实现提取内容

           /**
            * 子表达式是使用括号()将其包裹起来作为一个整体,这样在括号之后重复次数等都将被作为一个整体来控制;
            * 并且在匹配字符串的时候,每一次命中,括号匹配到的内容都可以单独作为一个子项提取出来。
            */
           private static void check(){
               System.out.println( "-----------测试子表达式开始-------------");

               String str = "<h2>dddddddddddd</h2><h3>ffffffffffffffffffff</h3>";
               String regStr = "<([hH][1-6])>.*?</(\\1)>";
               Pattern regPattern = Pattern.compile(regStr);
               Matcher matcher = regPattern.matcher(str);
               while( matcher.find()){
                   System.out.println( "matcher=" + matcher.group());
                   for( int i=0 ; i < matcher.groupCount() ; i++ ){
                       System.out.println( matcher.group( i));
                  }
               }

               System.out.println( "-----------测试子表达式结束-------------");
           }

       2、使用子表达式实现替换字符串

           /**
            * 测试替换字符串,注意只有replaceAll才支持正则表达式替换,这个非常有用
            */
           private static void test6(){
               System.out.println( "-----------测试替换字符串开始-------------");

               String str = "<h2>dddddddddddd</h2><h2>ffffffffffffffffffff</h3>";
               String regStr = "<([Hh][1-6])>.*?(</\\1>)";
               str = str.replaceAll( regStr, "$1ttttttttttt$2");
               System.out.println( "str=" + str);

               System.out.println( "-----------测试替换字符串结束-------------");
           }

       3、使用正则表达式加密手机号码

           private String encodePhoneNum( String phone){
                   if(StringUtils.isEmpty( phone) || phone.length() != 11){
                      return phone;
                   }
                   return phone.replaceAll( "(\\d{3})\\d{4}(\\d{4})", "$1****$2");
          }

八、常见正则写法

       校验密码是否同时包含大写字母、小写字母、数字:(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z]).{6,20}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值