正则表达式

第十二天

正则表达式

1.正则表达式简介

  1. 正则表达式(Regular Expressions),是一个特殊的字符串,可以对普通的字符串进行校验检测等工作。正则表达式不是Java特有的,它是一套独立的语法,可以在java,c++,python等语言中使用。

  2. 正则表达式,最基本的使用场景是用来做校验,校验一个字符串是否满足预设的规则。在校验的基础 上,又添加了若干个其他的引用场景,例如: 批量的查找、替换、切割...

2.正则表达式语法

  • 字符串中常用方法
方法名以及返回值类型 解析
boolean matches(String regex) 判断this字符串是否匹配正则表达式regex
String[] split(String regex) 对this使用匹配上正则表达式的子串进行切分成字符串数组
replaceAll(String regex, String replacement) 将一个字符串中的所有的满足正则规则部分的字符串,替换成指定的字符串
replaceFirst(String regex, String replacement) 将一个字符串中的第一个满足正则规则部分的字符串,替换成指定的字符串
  • 字符集语法
表达式 解析
[] 表示匹配括号里的任意一个字符。
[abc] 字符集。匹配a 或者 b 或者 c
[^abc] 反向字符集。
[a-g] 字符范围。表示匹配所有的小写字母的任意一个。
[^a-z] 反向字符范围。匹配不在指定的范围内的任何字符。例如,"a-z"匹配任何不在"a"到"z"范围内的任何字符。
[A-Za-z] 表示匹配所有的小写字母和大写字母的任意一个。
[a-zA-Z0-9] 表示匹配所有的小写字母和大写字母和数字的任意一个。
[a-z&&bc] 表示匹配所有的小写字母除了b和c, 只要匹配上就是true.
\d 用于匹配数字字符中的任意一个 相当于[0-9]
\D 用于匹配非数字字符中的任意一个 相当于0-9
\w 匹配单词字符中的任意一个 单词字符就是[a-zA-Z0-9_]
\W 用于匹配非单词字符中的任意一个
\s 用于匹配空格,制表符,退格符,换行符等中的任意一个
\S 用于匹配非空格,制表符,退格符,换行符等中的任意一个
. 用于匹配任意一个字符
  • 量词语法
X? 匹配0个或1个
X* 匹配0个或1个以上
x+ 匹配1个以上
X{n} 匹配n个
X{m,} 匹配m个以上
X{m,n} 匹配m~n个
  • 分组语法
() 在正则表达式上可以使用()来进行对一些字符分组,并可以使用逻辑运算符|来进行选择匹配
  • ^和$
^ 表示严格从头匹配
$ 表示匹配到结尾

3.Pattern的简介

其实,Pattern这个类,才是真正来操作正则表达式的类,它位于java.util.regex包下。在String类中的提供的 matches 、split 、replace等方 法,其实都是对这个类中的某些方法的封装。

在我们调用String类中的提供的 matches 、split 、replace等方法时,底层就会创建一个Pattern对象。这样的做法效率是很低的。我们何不主动创建一个pattern,然后每次需要匹配就直接用它而不需要再次创建,大大提高了程序的效率。

static Pattern complie(String regex)

Pattern类的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式,

如: Pattern p=Pattern.compile("\\w+");

2.pattern()

返回正则表达式的字符串形式,其实就是返回Pattern.complile(String regex)的regex参数

复制代码
Pattern p=Pattern.compile("\\w+"); 
String regex = p.pattern();//返回 \w+ 

3.matcher(String str**)**

返回一个Matcher类型的对象。

复制代码
Matcher matcher = p.matcher("michael");

4.Matcher类

Pattern类只能做一些简单的匹配操作,要想得到更强更便捷的正则匹配操作,那就需要将Pattern与Matcher一起合作.Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持。简单来说,Matcher对象就是Pattern对象与字符串匹配的一个结果。

4.1 Matcher对象的获取

Matcher的构造方法是私有的,我们一般通过调用Pattern对象的matcher方法返回一个matcher。

复制代码
String info = "名字:wulei  地址:hunan  电话:010-82350555";
Pattern p = Pattern.compile("(名字:\\w+\\s+)|(地址:\\w+\\s+)|(电话:\\d{3}-\\d{8})");
Matcher matcher = p.matcher(info);

4.2 Matcher类型的匹配方法

Matcher对象提供了三个不同的匹配方式:**matches、 lookingAt()、find()。**三个方法均返回boolean类型,当匹配到时返回true,没匹配到则返回false

  1. boolean matches()

    1. 整个字符串必须符合正则表达式,才会返回true,否则返回false

    2. 复制代码
      String info = "123abc";
      Pattern p = Pattern.compile("\\d+");
      Pattern p1 = Pattern.compile("\\d+\\w+");
      Matcher matcher = p.matcher(info);
      Matcher matcher1 = p1.matcher(info);
      ​
      System.out.println(matcher.matches());//false
      System.out.println(matcher1.matches());//true
       
  2. boolean lookingAt()

    1. 字符串的开头符合使用的正则表达式,返回true。否则返回false。

    2. 复制代码
      System.out.println(matcher.lookingAt()); //true、
  3. boolean find()

    1. 对字符串进行匹配,匹配到的子串可以在任何位置.。每次调用它,matcher里面的匹配指针都会向后移。

    2. 复制代码
      Pattern p=Pattern.compile("\\d+"); 
      Matcher m=p.matcher("22bb23"); 
      m.find();//返回true 
      Matcher m2=p.matcher("aa2223"); 
      m2.find();//返回true 
      Matcher m3=p.matcher("aa2223bb"); 
      m3.find();//返回true 
      Matcher m4=p.matcher("aabb"); 
      m4.find();//返回false 
    3. 复制代码
      String info = "123abc456def789";
      Pattern p = Pattern.compile("\\d+");
      Matcher matcher = p.matcher(info);
      while(matcher.find()){
          System.out.println(matcher.group());
      }
      输出:
      123
      456
      789
  4. reset()

    1. 重置find()的指针。注意:lookingAt()会影响到find()查找的子字符串

    2. 复制代码
      String info = "123abc456def789";
      Pattern p = Pattern.compile("\\d+");
      Matcher matcher = p.matcher(info);
      System.out.println("执行lookingAt()后的group:");
      matcher.lookingAt();
      System.out.println(matcher.group());
      //matcher.reset();
      System.out.println("执行find():");
      while(matcher.find()){
         System.out.println(matcher.group());
      }
      ​
      输出:
         执行lookingAt()后的group:
      123
         执行find():
      456
      789

4.3 Matcher类型的详情方法

当我们执行完匹配操作后,我们常常需要获得匹配到的具体字符串。matcher对象能够使用group()、start()、end()方法来获取相关信息。

注意:这三个方法是基于我们matcher执行matches()|lookingAt()|find()并匹配成功的情况下才能使用,否则会抛出java.lang.IllegalStateException

  1. group()

    1. 返回匹配到的子字符串
  2. group(int index)

    1. 返回匹配到的子字符串里的第index个分组,group(0)=group()。
  3. start()

    1. 返回匹配到的子字符串在字符串中的索引位置
  4. start(int index)

    1. 返回匹配到的子字符串里的第index个分组开始的索引。
  5. end()

    1. 返回匹配到的子字符串的最后一个字符在字符串中的索引位置+1
  6. end(int index)

    1. 返回匹配到的子字符串里的第index个分组结束的索引+1。

    2. 复制代码
      String info = "123abc456def789";
      Pattern p = Pattern.compile("(\\d+)([a-z]+)");
      Matcher matcher = p.matcher(info);
      
      while (matcher.find()){
          System.out.println("start(1): " + matcher.start(1));
              System.out.println("start(2): " + matcher.start(2));
              System.out.println("end(1): " + matcher.end(1));
              System.out.println("end(2): " + matcher.end(2));
      }
      
      输出:
      start(1): 0
      start(2): 3
      end(1): 3
      end(2): 6
      start(1): 6
      start(2): 9
      end(1): 9
      end(2): 12
    3. 现在我们使用一下稍微高级点的正则匹配操作,例如有一段文本,里面有很多数字,而且这些数字是分开的,我们现在要将文本中所有数字都取出来,利用java的正则操作是那么的简单.

    4. 复制代码
      Pattern p=Pattern.compile("\\d+"); 
      Matcher m=p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com"); 
      while(m.find()) { 
           System.out.println(m.group()); 
      } 
      
      输出: 
      456456 
      0532214 
      123 
      
      如将以上while()循环替换成 
      while(m.find()) { 
           System.out.println(m.group()); 
           System.out.print("start:"+m.start()); 
           System.out.println(" end:"+m.end()); 
      } 
      则输出: 
      456456 
      start:6 end:12 
      0532214 
      start:19 end:26 
      123 
      start:36 end:39 
  7. int groupCount()

    1. 用于获取正则表达式中的小括号的个数。() 用于分组。

    2. 复制代码
      ​
      import java.util.regex.Matcher;
      import java.util.regex.Pattern;
      ​
      /**
       * 研究一下groupCount():
       */
      public class PatternDemo07Matcher05 {
          public static void main(String[] args) {
              Pattern pattern = Pattern.compile("(((c)a)(t))s");
              Matcher matcher = pattern.matcher("one cat, two cats in the yard");
              /**
               * int groupCount():
               * 作用:用于获取正则表达式中的小括号的个数。() 用于分组。
               */
              System.out.println(matcher.groupCount());
              while (matcher.find()) {
                  // 打印符合正则表达式的子串, 因此循环次数是xxxx次。
                  System.out.println(matcher.group());
              }
              /**
               * 使用小括号的个数来循环, 可以使用group的重载方法:
               * String group(int group)
               *
               * 注意:想要使用()的个数进行遍历,需要将指针移动到字符串之前,然后还需要调用一下find方法
               *
               * group(0): 表示的是对组进行拆分括号的整体的样子
               * group(1): 表示第一个括号
               * group(2): 表示第二个括号
               */
              matcher.reset();
              matcher.find();
              for (int i = 0; i <=matcher.groupCount(); i++) {
                  System.out.println(matcher.group(i));
              }
          }
      }
相关推荐
℡余晖^2 分钟前
每日面试题20:spring和spring boot的区别
java·spring boot·spring
poemyang6 分钟前
“同声传译”还是“全文翻译”?为何HotSpot虚拟机仍要保留解释器?
java·java虚拟机·aot·编译原理·解释执行
苦学编程的谢1 小时前
Spring AOP_2
java·后端·spring·java-ee
没有bug.的程序员1 小时前
《Spring Boot应用工程化提升:多模块、脚手架与DevTools》
java·运维·spring boot
Derek_Smart1 小时前
工业级TCP客户端高可靠连接架构设计与Netty优化实践
java·性能优化·netty
长安城没有风1 小时前
从 0 到 1 认识 Spring MVC:核心思想与基本用法(上)
java·spring boot·spring·java-ee·mvc
许野平2 小时前
Rust 同步方式访问 REST API 的完整指南
java·网络·rust·restful
设计师小聂!2 小时前
力扣热题100--------240.搜索二维矩阵
java·算法·leetcode·矩阵
aningxiaoxixi2 小时前
安卓audio 架构解析
java·架构·ffmpeg