文章目录
正则表达式
1、正则表达式演示
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 正则表达式演示,快速入门
* @date 2024/5/25 10:21:47
*/
public class Regexp_ {
public static void main(String[] args) {
//假定编写了爬虫获得了以下文本内容,
String content="1995年,互联网的蓬勃发展给了Oak机会。业界为了使死板、单调的静态网页" +
"能够“灵活”起来,急需一种软件技术来开发一种程序,这种程序可以通过网络传播并且" +
"能够跨平台运行。于是,世界各大IT企业为此纷纷投入了大量的人力、物力和财力。" +
"这个时候,Sun公司想起了那个被搁置起来很久的Oak,并且重新审视了那个用软件编写的" +
"试验平台,由于它是按照嵌入式系统硬件平台体系结构进行编写的,所以非常小,特别适用于" +
"网络上的传输系统,而Oak也是一种精简的语言,程序非常小,适合在网络上传输。Sun公司" +
"首先推出了可以嵌入网页并且可以随同网页在网络上传输的Applet(Applet是一种将小程序" +
"嵌入到网页中进行执行的技术),并将Oak更名为Java。5月23日,Sun公司在Sun world会议" +
"上正式发布Java和HotJava浏览器。IBM、Apple、DEC、Adobe、HP、Oracle、Netscape" +
"和微软等各大公司都纷纷停止了自己的相关开发项目,竞相购买了Java使用许可证,并为自己的" +
"产品开发了相应的Java平台。";
//获取文章中所有英文单词
//获取文章中所有数字
//获取文章中所有英文单词和数字
//(1)、传统方法:遍历文本得到英文单词(代码量大,效率低)
//(2)、用正则表达式
//1。创建一个pattern对象,模式对象,可以理解就是一个正则表达式对象
//Pattern pattern = Pattern.compile("[a-zA-Z]+");
//Pattern pattern = Pattern.compile("[0-9]+");
Pattern pattern = Pattern.compile("([a-zA-Z]+)|([0-9]+)");
//2。创建一个匹配器对象
/*
理解:就是matcher匹配器按照pattern(模式/样式),到content文本中去匹配
找到就返回true,否则就返回false
*/
Matcher matcher = pattern.matcher(content);
//3。下面开始循环匹配
while(matcher.find()){
//匹配内容/文本,放到matcher.group(0)
System.out.println("找到:"+matcher.group(0));
}
}
}
2、为什么要学习正则表达式
我们遇到的问题:
- 给你一个字符串(或文章),请你找出所有四个数字连在一起的子串?
- 给你一个字符串(或文章),请你找出所有四个数字连在一起的的子串,并且这四个数字要满足:第一位与第四位相同,第二位与第三位相同,比如1221、5775
- 请验证输入的邮件,是否复合电子邮件格式
- 请验证输入的手机号,是否符合手机号格式
为了解决上述问题,Java提供了正则表达式技术,专门用于处理类似文本问题;简单地说:正则表达式是对字符串执行模式匹配的技术
3、正则表达式的基本介绍
一个正则表达式,就是用某种模式去匹配字符串的一个公式。很多人因为他们看上去比较古怪而且复杂所以所以不敢去用,不过,经过练习后,就觉得这些复杂的表达式看起来还是相当简单的,而且,一旦你弄懂它们,你就能把数小时辛苦而且易错的文本处理工作缩短在几分钟(甚至几秒钟)内完成。
注意:正则表达式并不是只有Java才有,实际上很多编程语言都支持正则表达式进行字符串操作!
4、正则表达式的底层实现(重要!!!)
(1)实例分析
给你一段字符串(文本),请找出所有四个数字连载一起的子串,比如:1998
不分组的情况:
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 分析Java的正则表达式的底层实现(重要!!!!)
* @date 2024/5/25 15:37:03
*/
public class RegTheory {
public static void main(String[] args) {
String content="1998 年 12 月 8 日,第二代 Java 平台的企业版 J2EE 发布。1999 年 6 月,Sun 公司发布了" +
"第二代 Java 平台(简称为 Java2)的 3 个版本:J2ME(Java2 Micro Edition,Java2 平台的微型" +
"版),应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard Edition,Java 2 平台的" +
"标准版),应用于桌面环境;J2EE(Java 2Enterprise Edition,Java 2 平台的企业版),应" +
"用 3443 于基于 Java 的应用服务器。Java 2 平台的发布,是 Java 发展过程中最重要的一个" +
"里程碑,标志着 Java 的应用开始普及 9889";
//目标:匹配所有四个数字
//1、建立正则表达式规则
//说明:\\d 表示任意一个数字
String regStr="\\d\\d\\d\\d";
//2、创建模式对象[即正则表达式对象]
Pattern pattern = Pattern.compile(regStr);
//3、创建匹配器
//说明:创建匹配器matcher,按照正则表达式规则去匹配content字符串
Matcher matcher = pattern.matcher(content);
//4、开始匹配
/*
matcher.find() 完成的任务
1、根据指定的规则,定位满足规则的子字符串(比如1998)
2、找到后,将子字符串的开始索引记录到matcher对象的属性 int[] groups;
groups[0]=0, 把该子字符串的结束的索引+1的值记录到groups[1]=4
3、同时记录oldLast的值为子字符串的结束的索引+1的值即35,及下次执行find时,就从4开始匹配
matcher.group(0) 分析
源码:
public String group(int group) {
if (first < 0)
throw new IllegalStateException("No match found");
if (group < 0 || group > groupCount())
throw new IndexOutOfBoundsException("No group " + group);
if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
return null;
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
1. 根据groups[0]=0 和 groups[1]=4 的记录的位置,从content开始截取子字符串返回
就是[0,4) 包含0但是不包含索引为4的位置
如果再次指向find方法,仍然按上面的分析来执行
*/
while(matcher.find()){
System.out.println("找到:"+matcher.group(0));
}
}
}
分组的情况:
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 分析Java的正则表达式的底层实现(重要!!!!)
* @date 2024/5/25 15:37:03
*/
public class RegTheory {
public static void main(String[] args) {
String content="1998 年 12 月 8 日,第二代 Java 平台的企业版 J2EE 发布。1999 年 6 月,Sun 公司发布了" +
"第二代 Java 平台(简称为 Java2)的 3 个版本:J2ME(Java2 Micro Edition,Java2 平台的微型" +
"版),应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard Edition,Java 2 平台的" +
"标准版),应用于桌面环境;J2EE(Java 2Enterprise Edition,Java 2 平台的企业版),应" +
"用 3443 于基于 Java 的应用服务器。Java 2 平台的发布,是 Java 发展过程中最重要的一个" +
"里程碑,标志着 Java 的应用开始普及 9889";
//目标:匹配所有四个数字
//1、建立正则表达式规则
//说明:\\d 表示任意一个数字
String regStr="(\\d\\d)(\\d\\d)";
//2、创建模式对象[即正则表达式对象]
Pattern pattern = Pattern.compile(regStr);
//3、创建匹配器
//说明:创建匹配器matcher,按照正则表达式规则去匹配content字符串
Matcher matcher = pattern.matcher(content);
//4、开始匹配
/*
matcher.find() 完成的任务(考虑分组的情况)
什么是分组?比如(\d\d)(\d\d),正则表达式中有() 表示分组,第1个() 表示第一组,第2个() 表示第二组...
1、根据指定的规则,定位满足规则的子字符串(比如(19)(98))
2、找到后,将子字符串的开始索引记录到matcher对象的属性 int[] groups;
2-1、groups[0]=0, 把该子字符串的结束的索引+1的值记录到groups[1]=4
2-2、记录1组()匹配到的字符串 groups[2]=0 groups[3]=2
2-3、记录2组()匹配到的字符串 groups[4]=2 groups[5]=4
2-4、如果有更多的分组,以此类推...
3、同时记录oldLast的值为子字符串的结束的索引+1的值即35,及下次执行find时,就从4开始匹配
matcher.group(0) 分析
源码:
public String group(int group) {
if (first < 0)
throw new IllegalStateException("No match found");
if (group < 0 || group > groupCount())
throw new IndexOutOfBoundsException("No group " + group);
if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
return null;
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
1. 根据groups[0]=0 和 groups[1]=4 的记录的位置,从content开始截取子字符串返回
就是[0,4) 包含0但是不包含索引为4的位置
如果再次指向find方法,仍然按上面的分析来执行
*/
while(matcher.find()){
/*
小结:
1、如果正则表达式有() 及分组
2、取出匹配的字符串规则如下
3、group(0) 表示匹配到的子字符串
4、group(1) 表示匹配到的子字符串的第一组字串
5、group(2) 表示匹配到的子字符串的第二组字串
6、。。。但是分组的数不能越界
*/
System.out.println("找到:"+matcher.group(0));
System.out.println("第一组()匹配到的值="+matcher.group(1));
System.out.println("第二组()匹配到的值="+matcher.group(2));
}
}
}
5、正则表达式语法
(1)基本介绍
如果想要灵活的运用正则表达式,必须了解其中各种元字符的功能,元字符从功能上大致分为:
- 限定符
- 选择匹配符
- 分组组合和反向引用符
- 特殊字符
- 字符匹配符
- 定位符
(2)元字符Metacharacter–转义号 \\
在我们使用正则表达式去检索某些特殊字符的时候,需要用到转移符号,否则检索不到结果,甚至会报错。注意:在Java的正则表达式中,两个\代表其他语言中的一个\
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 演示元字符-->转义号 \\的使用
* @date 2024/5/25 22:09:08
*/
public class RegExp02 {
/*
步骤:
1、建立规则 String regStr=" ";
2、创建模式对象[正则表达式对象] Pattern pattern = Pattern.compile(regStr);
3、创建匹配器 Matcher matcher = pattern.matcher(content);
4、进行匹配
while(matcher.find()){
System.out.println("找到"+matcher.group(0));
}
*/
public static void main(String[] args) {
String content="abc$(a.bc(123()";
//匹配( => \\(
//String regStr="\\(";
//匹配. => \\.
//String regStr="\\.";
//String regStr="\\d\\d\\d";
String regStr="\\d{3}";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println("找到"+matcher.group(0));
}
//需要用到转义字符的符号有以下:. * + ( ) $ / \ ? [ ] ^ { }
}
}
(3)元字符–字符匹配符
符号 | 含义 | 示例 | 解释 | 匹配输入 |
---|---|---|---|---|
[] | 可接受的字符列表 | [abc] | a、b、c中任意一个 | |
[^] | 不接受的字符列表 | [^abc] | 除a、b、c之外的任意一个字符,包括数字或特殊符号 | |
- | 连字符 | A-Z | 任意单个大写字母 | |
. | 匹配除\n以外的任何字符 | a…b | 以a开头,b结尾,中间包括2个任意字符的长度为4的字符串 | a12b,acdb,a&*b |
\\d | 匹配单个字符,相当于[0-9] | \\d{3}(\\d)? | 包含3个或4个数字的字符串 | 123,1234 |
\\D | 匹配非数字字符,相当于[^0-9] | \\D(\\d)* | 以单个非数字字符开头,后接任意个 数字字符串 | a,A123 |
\\w | 匹配单个数字、大小写字母字符,相当于[0-9a-zA-Z] | \\d{3}\\w{4} | 以3个数字开头的长度为7的数字字母字符串 | 123abcd,12345pe |
\\W | 匹配单个非数字、大小写字母字符,相当于[^0-9a-zA-Z] | \\W+\\d{2} | 以至少1个非数字字母字符开头,2个数字字符结尾的字符串 | #23,#?@22 |
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 演示字符匹配符的使用
* @date 2024/5/26 10:21:26
*/
public class RegExp03 {
public static void main(String[] args) {
String content="a11c8abc_ABCy@.";
//String regStr="[a-z]";//匹配a-z之间任意一个字符
//String regStr="[A-Z]";//匹配A-Z之间任意一个字符
//String regStr="abc";//匹配 abc 字符串[默认区分大小写]
//String regStr="(?i)abc";//匹配 abc 字符串[不区分大小写]
//String regStr="[0-9]";//匹配0-9之间任意一个字符
//String regStr="[^a-z]";//匹配不在a-z之间的任意一个字符
//String regStr="[^0-9]";//匹配不在0-9之间的任意一个字符
//String regStr="[abcd]";//匹配在abcd之间的任意一个字符
//String regStr="\\D";//匹配不在0-9之间的任意一个字符
//String regStr="\\w";//匹配大小写英文字母、数字、下划线
//String regStr="\\W";//相当于[^a-zA-Z0-9]
//String regStr="\\s";//匹配任何空白字符(空格,制表符等)
//String regStr="\\S";//和\\s相反 匹配任何非空白字符
String regStr=".";//匹配出\n之外的所有字符,如果要匹配.本身则需要使用\\.
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println("找到="+matcher.group(0));
}
}
}
(4)元字符–选择匹配符
在匹配某个字符串的时候是选择性的,即:可以匹配这个,又可以匹配那个,这时你需要用到 选择匹配符号 |
符号 | 含义 | 示例 | 解释 |
---|---|---|---|
| | 匹配"|"之前或之后的表达式 | ab|cd | ab或者cd |
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 演示选择匹配符
* @date 2024/5/26 10:43:16
*/
public class RegExp04 {
public static void main(String[] args) {
String content="du 杜 Ghost-D";
String regStr="du|杜|D";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println("找到="+matcher.group(0));
}
}
}
(5)元字符–限定符
用于指定其前面的字符和组合项连续出现多少次
符号 | 含义 | 示例 | 说明 | 匹配输入 |
---|---|---|---|---|
* | 指定字符重复0次或n次(无要求)零到多 | (abc)* | 仅包含任意个abc的字符串 | abc,abcabcabc |
+ | 指定字符重复1次或n次(至少1次)1到多 | m+(abc)* | 以至少1个m开头,后接任意个abc的字符串 | m,mabc,mmmabc |
? | 指定字符重复0次或1次(最多1次)0到1 | m+abc? | 以至少1个m开头,后接ab或abc的字符串 | mab,mabc,mab,mmabc |
{n} | 只能输入n个字符 | [abcd]{3} | 由abcd中字母组成的任意长度为3的字符串 | abc,dbc,adc |
{n,} | 指定至少n个匹配 | [abcd]{3,} | 由abcd中字母组成的任意长度不小于3的字符串 | aab,dbc,aaaabbbc |
{n,m} | 指定至少n个但不多于m个匹配 | [abcd]{3,5} | 由abcd中字母组成的任意长度不小于3,不大于5的字符串 | abc,abcd,aaaaa |
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 演示限定符
* @date 2024/5/26 10:49:03
*/
public class RegExp05 {
public static void main(String[] args) {
String content="a2111111aaaaaahello";
//String regStr="a{3}";//匹配aaa
//String regStr="1{4}";//匹配1111
//String regStr="\\d{2}";//匹配两个任意数字字符
/*
细节:Java匹配默认贪婪匹配,即尽可能匹配多的
*/
//String regStr="a{3,4}";//表示匹配aaa或者aaaa,他会先匹配有aaaa的
//String regStr="\\d{2,5}";//表示匹配2位数或者3位数,4位数,5位数
//1+
//String regStr="1+";//匹配一个或多个1
//String regStr="\\d+";//匹配一个或多个数字
//1*
//String regStr="1*";//匹配0个或者多个1
//演示?的使用,遵循贪婪匹配
String regStr="a2?";//匹配a或者a2
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println("找到="+matcher.group(0));
}
}
}
(6)元字符–定位符
规定要匹配的字符串出现的位置,比如在字符串的开始还是在结束的位置,这个也是相当有用的。
符号 | 含义 | 示例 | 说明 | 匹配输入 |
---|---|---|---|---|
^ | 指定起始字符 | 1+[a-z]* | 以至少一个数字开头,后接任意个小写字母的字符串 | 123,6aa,555edf |
$ | 指定结束字符 | 2\\-[a-z]+$ | 以1个数字开头后接连字符"-",并以至少1个小写字母结尾的字符串 | 1-a |
\\b | 匹配目标字符串的边界 | Ghost\\b | 这里说的字符串的边界指的是子串间有空格,或者是目标字符串的结束位置 | 123Ghost |
\\B | 匹配目标字符串的非边界 | Ghost\\B | 和\\b相反 | Ghost-D |
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 演示定位符的使用
* @date 2024/5/26 17:42:29
*/
public class RegExp06 {
public static void main(String[] args) {
String content="hanshunping sphan nnhan";
//String content="123-abc";
//String regStr="^[0-9]+[a-z]*";//以至少1个数字开头,后接任意个小写字母的字符串
//String regStr="^[0-9]+\\-[a-z]+$";//以至少1个数字开头,必须以至少一个小写字母结束
//String regStr="han\\b";//表示匹配边界的han[这里的边界是指:被匹配的字符串最后,也可以是空格的子字符串的后面]
String regStr="han\\B";//和\\b含义相反
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println("找到="+matcher.group(0));
}
}
}
(7)分组
常用分组构造形式 | 说明 |
---|---|
(pattern) | 非命名捕获。捕获匹配的子字符串。编号为零的第一个捕获是由整个正则表达式模式匹配的文本,其他捕获结果则根据左括号的顺序从1开始自动编号 |
(?<name>pattern) | 命名捕获,将匹配的子字符串捕获到一个组名称或编号名称中,用于name的字符串不能包含任何标点符号,并且不能以数字开头。可以使用单引号替代尖括号,例如(?‘name’) |
(?:pattern) | 匹配pattern但是不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储以后使用的匹配。者对于用"or"字符(|)组合模式部件的情况很有用。例如industr(?:y|ies)是比industry|industries更经济的表达式。 |
(?=pattern) | 它是一个非捕获匹配。例如windows(?=95|98|NT|2000)匹配"windows 2000"的windows,但是不匹配"windows 3.1"的windows |
(?!pattern) | 该表达式匹配不处于匹配pattern的字符串的起始点的搜索字符串。它是一个非捕获匹配,例如例如windows(?!95|98|NT|2000)匹配"windows 3.1"的windows,但是不匹配"windows 2000"的windows。 |
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 演示分组的使用
* @date 2024/5/26 17:53:11
*/
public class RegExp07 {
public static void main(String[] args) {
String content="hanshunping s7789 nn1189han";
//下面是非命名分组
/*
说明:
1、matcher.group(0) 得到匹配到的字符串
2、matcher.group(1) 得到匹配到的字符串的第1个分组内容
3、matcher.group(2) 得到匹配到的字符串的第2个分组内容
*/
//String regStr="(\\d\\d)(\\d\\d)";//匹配4个数字的字符串
//命名分组:即可以给分组取名
String regStr="(?<g1>\\d\\d)(?<g2>\\d\\d)";//匹配4个数字的字符串
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println("找到="+matcher.group(0));
System.out.println("第1个分组内容="+matcher.group(1));
System.out.println("第1个分组内用[通过组名]="+matcher.group("g1"));
System.out.println("第2个分组内容="+matcher.group(2));
System.out.println("第2个分组内用[通过组名]="+matcher.group("g2"));
}
}
}
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 演示非捕获分组,语法比较奇怪
* @date 2024/5/26 20:54:57
*/
public class RegExp08 {
public static void main(String[] args) {
String content="hello 韩顺平教育 jack 韩顺平老师 韩顺平同学 hello 韩顺平学生";
//找到韩顺平教育、韩顺平老师、韩顺平同学 子字符串
//String regStr="韩顺平教育|韩顺平老师|韩顺平同学";
//上面的写法可以等价非捕获分组,注意:不能matcher.group(1)
//String regStr="韩顺平(?:教育|老师|同学)";
//找到 韩顺平 这个关键字,但是要求只是查找韩顺平教育和韩顺平老师 中包含有的韩顺平
//下面也是非捕获分组,不能使用matcher.group(1)
//String regStr="韩顺平(?=教育|老师)";
//找到 韩顺平 这个关键字,但是要求只是查找 不是 (韩顺平教育 和 韩顺平老师)中包含有的韩顺平
//下面也是非捕获分组,不能使用matcher.group(1)
String regStr="韩顺平(?!教育|老师)";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println(matcher.group(0));
}
}
}
6、应用实例
(1)对字符串进行如下验证
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 应用实例
* @date 2024/5/26 21:14:11
*/
public class RegExp10 {
public static void main(String[] args) {
String content="13588889999";
//汉字
//String regStr="^[\u0319-\uffe5]+$";
//邮政编码 1、是1-9开头的一个六位数,比如:123890
//String regStr="^[1-9]\\d{5}$";
//QQ号码 1、是1-9开头的一个(5位数-10位数) 比如 12389,1345687,187698765
//String regStr="^[1-9]\\d{4,9}$";
//手机号码 1、必须以13,14,15,18 开头的11位数,比如13588889999
String regStr="^1[3|4|5|8]\\d{9}$";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
if (matcher.find()){
System.out.println("满足格式");
}else {
System.out.println("不满足格式");
}
}
}
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description
* @date 2024/5/26 21:30:07
*/
public class RegExp11 {
public static void main(String[] args) {
String content="https://fanyi.baidu.com/mtpe-individual/multimodal#/";
String regStr="^((http|https)://)?([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.#]*)?$";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
if (matcher.find()){
System.out.println("满足格式");
}else {
System.out.println("不满足格式");
}
}
}
7、正则表达式三个常用类
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description 演示matches方法,用于整体匹配,在验证输入的字符串是否腕足条件使用
* @date 2024/5/27 09:09:40
*/
public class PttternMethod {
public static void main(String[] args) {
String content="hello abc hello,韩顺平教育";
//String regStr="hello";
String regStr="hello.*";
boolean matches = Pattern.matches(regStr, content);
System.out.println("整体匹配="+matches);
}
}
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description Matcher 类的常用方法
* @date 2024/5/27 09:17:27
*/
public class MatcherMethod {
public static void main(String[] args) {
String content="hello edu jack hspedutom hello smith hello smith hello hspedu hspedu";
String regStr="hello";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while(matcher.find()){
System.out.println("======================");
System.out.println(matcher.start());
System.out.println(matcher.end());
System.out.println("找到:"+content.substring(matcher.start(), matcher.end()));
}
//整体匹配法,常用于,去校验某个字符串是否满足某个规则
System.out.println("整体匹配="+matcher.matches());
//完成如果content有hspedu 替换成 韩顺平教育
regStr="hspedu";
pattern=Pattern.compile(regStr);
matcher=pattern.matcher(content);
//注意:返回的字符串才是替换后的字符串 原来的content不变化
String newContent=matcher.replaceAll("韩顺平教育");
System.out.println("newContent="+newContent);
System.out.println("content="+content);
}
}
8、分组,捕获,反向引用
(1)提出需求
给你一段文本,请找出所有四个数字连在一起的子串,并且这四个数字要满足第一位与第四位相同,第二位与第三位相同,比如1221
(2)介绍
- 分组
我们可以用圆括号组成一个比较复杂的匹配模式,那么一个圆括号的部分我们可以看作是一个子表达式/一个分组
- 捕获
把正则表达式中子表达式/分组匹配的内容,保存到内存中以数字编号或显示命名的组里,方便后面引用,从左往右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。组0代表的是整个正则式
- 反向引用
圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部,内部反向引用\\分组号,外部反向引用$分组号
//匹配两个连续的相同的数字
String regStr="(\\d)\\1";
//匹配五个连续的相同的数字
String regStr="(\\d)\\1{4}";
//匹配个位与千位相同,十位与百位相同的数
String regStr="(\\d)(\\d)\\2\\1";
//满足前面是一个5位数,然后一个"-"号,然后是一个9位数,连续的每3位要相同 12321-333999111
String regStr="\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}";
package regexp;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description
* @date 2024/5/27 09:32:55
*/
public class RegExp12 {
/*
要求:把: "我....我要....学学学学....编程 java!"
通过正则表达式修改成"我要学编程 java"
*/
public static void main(String[] args) {
String content = "我....我要....学学学学....编程 java!";
//第一步:去除.
String regStr = "\\.";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
content = matcher.replaceAll("");
//System.out.println("content="+content);
// //第二步:去除重复字
// pattern=Pattern.compile("(.)\\1+");
// matcher=pattern.matcher(content);
// while(matcher.find()){
// System.out.println("找到="+matcher.group(0));
// }
// //使用反向引用$1来替换匹配到的内容
// content=matcher.replaceAll("$1");
// System.out.println("content="+content);
content = Pattern.compile("(.)\\1+").matcher(content).replaceAll("$1");
System.out.println(content);
}
}
9、String类中使用正则表达式
(1)替换功能
(2)判断功能
(3)分割功能
package regexp;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description
* @date 2024/5/27 09:52:26
*/
public class StringReg {
public static void main(String[] args) {
String content="2000 年 5 月,JDK1.3、JDK1.4 和 J2SE1.3 相继发布,几周后其" +
"获得了 Apple 公司 Mac OS X 的工业标准的支持。2001 年 9 月 24 日,J2EE1.3 发" +
"布" +
"2002 年 2 月 26 日,J2SE1.4 发布。自此 Java 的计算能力有了大幅提升";
//使用正则表达式,将JDK1.3 和 JDK1.4 替换成JDK
content=content.replaceAll("JDK1\\.3|JDK1\\.4","JDK");
System.out.println(content);
//要求 验证一个手机号,要求必须是以138 139开头的
content="13888889999";
if (content.matches("1(38|39)\\d{8}")){
System.out.println("验证成功");
}else {
System.out.println("验证失败");
}
//要求按照#或者-或者~或者数字来分割
System.out.println("=====================");
content="hello#abc-jack12smith~北京";
String[] split = content.split("#|-|~|\\d+");
for (String s : split) {
System.out.println(s);
}
}
}
10、本章作业
1、
package regexp.homework;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description
* @date 2024/5/27 20:48:55
*/
public class homework01 {
public static void main(String[] args) {
String content="2479970653@qq.com";
String regStr="^([\\w_-]+)@([a-zA-Z.]+)$";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
if (matcher.matches()){
System.out.println("匹配成功");
}else {
System.out.println("匹配失败");
}
}
}
2、
package regexp.homework;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description
* @date 2024/5/27 20:49:03
*/
public class homework02 {
public static void main(String[] args) {
String content="123.015";
String regStr="^[+|-]?([1-9]\\d*|0)(\\.\\d+)?$";
if (content.matches(regStr)){
System.out.println("匹配成功");
}else {
System.out.println("匹配失败");
}
}
}
3、
package regexp.homework;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description
* @date 2024/5/28 08:54:28
*/
public class homework03 {
public static void main(String[] args) {
String content="https://www.baidu.com:8080/index.html";
String regStr="^([a-zA-Z]+)://([a-zA-Z.]+):(\\d+)[\\w-/]*/([\\w.]+)$";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
if (matcher.matches()){
System.out.println("匹配成功");
}else {
System.out.println("匹配失败");
}
}
}
if (content.matches(regStr)){
System.out.println("匹配成功");
}else {
System.out.println("匹配失败");
}
}
}
### 3、
[外链图片转存中...(img-PmutKqme-1716966962743)]
```java
package regexp.homework;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author D
* @version 1.0
* @project regular_expression
* @description
* @date 2024/5/28 08:54:28
*/
public class homework03 {
public static void main(String[] args) {
String content="https://www.baidu.com:8080/index.html";
String regStr="^([a-zA-Z]+)://([a-zA-Z.]+):(\\d+)[\\w-/]*/([\\w.]+)$";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
if (matcher.matches()){
System.out.println("匹配成功");
}else {
System.out.println("匹配失败");
}
}
}