网站Logo 苏叶的belog

正则表达式

wdadwa
3
2025-12-20

一,正则表达式介绍

正则表达式:校验字符串是否满足一定的规则,用来校验数据格式的合法性

作用:校验字符串是否满足规则,在一段文本中查询满足要求的内容。

  • 使用方式(java 中)

    String str="123456";
    str.matches("正则表达式内容");
    

使用规则

  1. 字符类型(只匹配一个字符

    表达式说明
    [abc]只能是a,b,或c
    [^abc]除了a,b,c之外的字符
    [a-zA-Z]a到z,或A到Z,包括(范围)
    [a-d[m-p]]a到d,或m到p
    [a-z&&[def]]a-z和def的交集:def
    [a-z&&[^def]]a-z和非def的交集:等同于:[ad-z]
    [a-z&&[^m-p]]a到z和除了m到p的交集:等同于[a-lq-z]
    [0-9]只能为字符0到9

    字符类表示比如说:

    "abc" 然后 [abc] 这个是对第一个字符 a 进行匹配!后面的 bc 如果也需要匹配就写成 [abc][abc][abc] 这样的形式

  2. 预定义字符(只匹配一个字符!)

    表达式说明
    .任何字符,除了\n和\r
    \d一个数字:相当于[0-9]
    \D非数字,相当于:[^0-9]
    \s一个空白字符:相当于[\t\n\x0B\f\r]
    \S非空白字符
    \w相当于[a-zA-Z_0-9]英文,数字,下划线
    \W[^\w]一个非单词字符

    注意:在 java 当中 \ 是代表转义字符,如果想写正则表达式需要写 \\d 这种,意思就是把 \d 转义成 \\d

    如果不写就代表把字符 d 转义!

  3. 数量词

    表达式说明
    X??前面的X出现1次或者0次
    X**前面的X出现0次或者多次
    X++前面的X出现1次或多次
    X{n}X这个出现n次
    X{n,}X这个出现n次及以上
    x{n,m}X这至少n次但不超过m次

    小细节:X 可以是单个字符也可以是一组

    ab+ 表示的是第一个字符必须为 a,第二个字符可以是 b 并且可以在后面出现 1 次或多次,这里的 X 代表字符

    a(bc)+ 表示的是第一个字符必须为 a,后面进行了分组,这里的 X 是 bc,且 bc 在后面要出现 1 次或多次

  4. 符号

    符号说明举例
    []表示里面的内容只出现一次[0-9]
    ()分组a(bc)+表示,bc这一组至少出现一次,等同于 abcbcbc...(bc至少出现一次)
    ^取反[^abc]
    &&两个范围的交集[a-z&&A-Z]
    |写在方括号外面表示并集x|X
    .任意字符\n回车符号不匹配!
    \转义字符\\d
    (?i)忽略后面字符的大小写(?i)abc
    只忽略b的大小写a((?i)b)c

二,java使用正则表达式

需要的类:

  • Pattern:表示正则表达式类
  • Matcher:文本匹配器,作用按照正则表达式的规则去读取字符串,从头开始读取

使用方法:

Pattern p=Pattern.compile("正则表达式");//获取Pattern对象
Matcher m=p.matcher(str);//str里面是文本内容,字符串格式的
//m:文本匹配器
//p:规则
//str:文本
//m要在str中找到符合p规则的小串
m.find();//拿着文本匹配器,从头开始找满足规则的字串,如果有返回true,没有返回false
//找到后会在底层记录小串的起始索引和结束索引+1,之所以+1是因为调用的是substring这个方法剪切的小串!
String s1=m.group();//这个方法会把找到的小串获取出来


//总体来写:
String str="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个版本是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会登上历史的舞台";
Pattern p=Pattern.compile("java\\d{0,2}");
Matcher m=p.matcher(str);
while(m.find()){
    String s=m.group();
    sout(s);
}

三,带条件的爬取数据

String str="Java自从95年问世以来,经历了很多版本,目前企业中用的最多的是Java8和Java11,因为这两个版本是长期支持版本,下一个长期支持版本是Java17,相信在未来不久Java17也会登上历史的舞台";
//需求1:爬取版本号为8,11,17的java文本,但是只要java文本不要版本号
String regex="Java(?=8|11|17)"//这里是?=
Pattern p=Pattern.compile(regex);
Matcher m=p.matchers(s);
while(m.find()){
	System.out.println(m.group());
}
//需求2:爬取版本号为8,11,17的java文本,正确爬取结果为:java8,java11 java 17 
String regex="Java(?:8|11|17)"//这里是?:
Pattern p=Pattern.compile(regex);
Matcher m=p.matchers(s);
while(m.find()){
	System.out.println(m.group());
}
//需求3:爬取除了版本号为8,11,17的文本
String regex="Java(?!8|11|17)"//这里是!
Pattern p=Pattern.compile(regex);
Matcher m=p.matchers(s);
while(m.find()){
	System.out.println(m.group());
}

Java(?=8|11|17) 解释:? 相当于前面的 J 数据 ava,= 代表 Java 后面要跟随 8 或 11 或 17,但是在获取的时候只获取前半部分 Java

Java(?:8|11|17) 解释:? 相当于前面的数据 java,: 代表 Java 后面要跟随 8 或 11 或 17,并且在获取的时候后面要跟随数字 8 或 11 或 17

Java(?!8|11|17) 解释:? 相当于前面的数据 java,! 代表爬取 Java 后面跟随的除了 8 或 11 或 17 的 java 文本

四,贪婪爬取和非贪婪爬取

贪婪爬取:在爬取的时候尽可能多的爬取数据

非贪婪爬取:在爬取的时候尽可能少的爬取数据

Java 默认使用贪婪爬取,但是在数量词 +,* 后面加上? 就是非贪婪爬取

String str="<h1>hello world</h1>";
//贪婪爬取
String regex="<.*>"
Pattern p=Pattern.compile(regex);
Matcher m=p.matchers(s);
while(m.find()){
	System.out.println(m.group());
}
//结果:<h1>hello world</h1>		
//分析:贪婪爬取<,*>	其中.*代表所有字符	<代表头部的<		>代表尾部的>
//在正则表达式看来是:<h1	hello world	/h1>这样的匹配形式
//非贪婪爬取
String regex="<.*?>?"
Pattern p=Pattern.compile(regex);
Matcher m=p.matchers(s);
while(m.find()){
	System.out.println(m.group());
}
//结果:<h1>	
//		</h1>

五,正则表达式在字符串中的使用

  • 常用的,还有其他的可以在API帮助文档中查。。。
方法名说明
public String[] matches(String 正则表达式)判断字符串是否满足正则表达式规则
public String replaceAll(String 正则表达,String 新字符串)把满足正则表达式的小串替换为新的字符串
public String[] split(String 正则表达式)把满足正则表达式的小串分割

六,捕获分组和非捕获分组

正则表达式当中,每一组都是有组号的,也就是序号。

小括号代表的就是分组

  • 规则 1:从 1 开始,连续不间断

  • 规则 2:以左括号为基准,最左边的是第一组,其次为第二组,依次递推

(\\d+)(\\d*)(\\d?) 其中 (\d+) 代表第一组,(\\d*)第二组,(\\d?)第三组

(\\d+(\\d+))(\\d+) 这里第二个 \\d+ 是第二组!因为规则 2

  • 捕获分组:把这一组比如说第二组中的数据,拿出来再用依次
//判断一个字符串的开始字符和结束字符是否一致,只考虑一个字符
举例:a123a	b123b	122241	&a3fsfes&
正则表达式:(.).+(.)\\1
    \\1表示把第一组的数据(.)拿出来再用一次
    \\X	表示把第X组的数据拿出来再用一次
//判断一个字符串的开始和结束字符是否一致,可以有多个字符
举例:abc123abc	bbdb123bdbb
正则表达式:(.+).+\\1
//判断一个字符串的开始和结束部分是否一致,开始部分内部的每个字符也需要一致
举例:aaa123aaa	bbb123bbb
正则表达式:((.)\\2*).+\\1*
(.)表示把首字母看做一组
//2表示把首字母拿出再次使用
*作用于\\2表示后面重复的内容出现0次或多
.+表示中间任意字符出现1次或多次
\\1表示((.)\\2*)
*表示\\1出现0次或多次
//需求:将字符串:我要学学学编编编编程程程程程程
//    替换为:我要学编程
String str="我要学学学编编编编程程程程程程";
String result=str.replaceAll("(.)\\1+","$1");
replaceAll是String自带的方法,第一个是正则表达式,第二个$1表示在正则表达式中使用第一个分组的内容

在正则表达式中调用分组用 \ 组号 在正则表达式外用分组是用 $ 组号

  • 非捕获分组:分组之后不需要在使用本组数据,仅仅只是把数据括起来(不占用组号)
符号含义举例
(?:正则)获取所有Java(?:8|11|17)
(?=正则)获取前面部分Java(?=8|11|17)
(?!正则)获取不是指定内容的前面部分Java(?!8|11|17)
动物装饰