韩顺平Java | C27 正则表达式

入门介绍

需求:提取文本中某类字符

传统方法:遍历每个字符,判断其是否在ASCII码中某种类型得编码范围内,代码量大,效率不高

正则表达式(RegExp, regular expression):处理文本的利器,是对字符串执行模式匹配的技术。java\javascript\php等语言都支持。

java 复制代码
//假设爬虫获取内容
String content = "...";
//1 先创建一个Pattern模式对象,即一个正则表达式对象
//提取所有英文单词
Pattern pattern = Pattern.compile("[a-zA-Z]+");
//提取所有数字
Pattern pattern = Pattern.compile("[0-9]+");
//提取所有数字和英文单词
Pattern pattern = Pattern.compile("([0-9]+)|([a-zA-Z]+)");
//提取百度热搜的标题
Pattern pattern = Pattern.compile("<a target=\"_blank\" title=\"(\\S*)\"");
//提取文本中的ip地址
Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d+")
//2 创建一个匹配器对象,按照模式到content中匹配,找到返回true,否则false
Matcher matcher = pattern.matcher(content);
//3 开始循环匹配
while (matcher.find()) {
	//匹配内容,文本,放到m.group(0)
	System.out.println("找到:" + matcher.group(0)); //热搜标题使用group(1)
}

正则底层实现

matcher.find():定位满足指定规则的字符串,将找到的子字符串的开始缩影记录到matcher的属性int\[\] groups中groups0;把结束索引+1的值记录到groups1,同时记录为oldLast的值,作为下次find开始的位置。
group(int group):根据groups2 \* group和groups2 \* group + 1从content截取字符串(前闭后开)并返回。

java 复制代码
String regStr = "\\d\\d\\d\\d"; //4个任意数字
group(0) //返回content中[group[0], group(1))的子字符串

String regStr = "(\\d\\d)(\\d\\d)"; //表示分组1和2
//另外还会把第1组匹配到的子字符串的开始索引和结束索引+1的值记录到group[2]和group[3];第2组对应值记录到group[4]和group[5]...
group(0) //返回匹配到的子字符串,content中[group[0], group(1))的子字符串
group(1) //返回匹配到的子字符串中的第1组,content中[group[2], group[3])的子字符串
group(2) //返回匹配到的子字符串中的第2组,content中[group[4], group[5])的子字符串

基本语法

元字符

转义符\\

使用正则表达式去检索某些特殊字符的时候,需要用到转义符号,将下一字符标记为特殊字符,如:. * + ( ) $ / \ ? [ ] ^ { }。Java正则表达式中\\代表其它语言中的一个\

字符匹配符


选择匹配符

限定符

指定其前面的字符和组合项连续出现多少次

定位符

e.g.^[0-9]+[a-z]$ 以至少1个数字作为行开头,后接至少一个小写字母作为行结尾的字符串,如可以匹配"123abc",不可匹配"123abc12"

分组

捕获分组

java 复制代码
String regStr = "(?<g1>\\d\\d)(?<g2>\\d)(?<g3>\\d)";
group("g1") //返回匹配到的子字符串中的第1组
group("g2") //返回匹配到的子字符串中的第2组
group("g3") //返回匹配到的子字符串中的第3组

非捕获分组

非贪婪匹配

Java正则表达式默认贪婪匹配
?当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。例如,在字符串"oooo"中,"o+?"只匹配单个"o",而"o+"匹配所有"o"。

※三个常用类

Pattern

Pattern对象时一个正则表达式对象。Pattern类没有公共构造方法。要创建一个Pattern对象,调用其公共静态方法,接收一个正则表达式作为它的第一个参数,它返回一个Pattern对象。Pattern r = Pattern.compile(pattern);

java 复制代码
Pattern类的方法
boolean isMatch = Pattern.matches(String pattern, String content); // 整体匹配,用于验证输入字符串是否满足条件使用
String content = "hello, world!";
String pattern = "hello"; //false
String regStr = "hello.*"; //true .*后跟 *任意个 .任意字符

Matcher

Matcher对象是对输入字符串进行解释和匹配的引擎。Matcher也没有公共构造方法。需要调用Pattern对象的matcher方法来获得一个Matcher对象。

PatternSyntaxException

非强制异常,表示一个正则表达式模式中的语法错误。

※分组、捕获、反向引用

分组:用圆括号组成一个比较复杂的匹配模式,一个个圆括号部分我们可以看作是一个子表达式/一个分组。

捕获:把正则表达式中子表达式/分组匹配的内容,保存到内存中以数字编号或显示命名的组里,0代表整个正则式,从左向右分组号依次是1,2...

反向引用:圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,称为反向引用。这种引用可以在正则表达式内部或外部,内部反向引用\\分组号,外部反向引用$分组号

java 复制代码
(\\d)\\1 //要匹配两个连续的相同数字
(\\d)\\1{4} //匹配连续5个相同数字
(\\d)(\\d)\\2\\1 //匹配个位与千位相同,十位与百位相同的数

String类中的正则表达式

替换

pubilc String replaceAll(String regex, String replacement)

java 复制代码
content.replaceAll("JDK1\\.3|JDK1\\.4", "JDK);

判断

pubilc boolean matches(String regex)

java 复制代码
phone.matches("13(8|9)\\d{8}"); //验证手机号以138或139开头

分割

pubilc String[] split(String regex)

java 复制代码
content = "hello#abc-jack12smith~北京":
String[] split = content.split("#|-|~|\\d+")
for (String s : split) {
	System.out.println(s); 
}
/**
* hello
* abc
* jack
* smith
* 北京
*/
相关推荐
坐吃山猪1 分钟前
【多线程】Semaphore使用
java·数据库·oracle·多线程
传奇开心果编程9 分钟前
【Rust入门知识点学与练】第3课:String 与 &str 的区别
开发语言·学习·rust
秋名RG20 分钟前
Java 核心特性一览
java·开发语言
霸道流氓气质25 分钟前
Spring AI 技术细节:RAG QuestionAnswerAdvisor 设计与实现
java·人工智能·spring
平头哥AI1 小时前
Day 01 | go run 跑通第一个 Go 程序,go build 留下一个能拷走的 exe
开发语言·后端·golang
斑马1391 小时前
Linux软件编程学习笔记(十二)——TCP并发服务器模型
java·服务器·网络
冬栈程序设计1 小时前
Springboot宿舍管理系统【670099】 -附源码(开箱即用)
java·毕业设计·springboot·课程设计·程序设计·大作业
2601_962284501 小时前
北京Java全栈开发培训 Web前端开发 软件测试就业培训班
java·软件测试·web前端·全栈开发·就业培训
葡萄城技术团队1 小时前
工业数据可视化:使用活字格 AIcoding + Three.js 构建轻量化三维设备监控大屏
开发语言·javascript·信息可视化
qiaosaifei2 小时前
JAVA老项目中有大量的类名_编译时报找不到符号错误
java·开发语言