正则表达式

第十二天

正则表达式

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));
              }
          }
      }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值