韩顺平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
* 北京
*/
相关推荐
我不是疯子是傻子12 分钟前
串口通信数据帧粘包拆包再进化:基于 Qt 的滑动窗口与 CRC 校验实战
开发语言·qt
程序员老陆20 分钟前
Qt中实现窗口真全屏(覆盖Windows任务栏)
开发语言·windows·qt
xiaohaiAIgeo21 分钟前
【2026年】HG/T 20656-2024化工暖通空调设计规范:新版标准的变化与影响
java·前端·javascript·科普知识
小强库计算机毕业设计36 分钟前
基于 Spring Boot + Vue3 的校园管理系统
java·spring boot·后端·项目实战·管理系统·技术分享·校园管理系统实战
霸道流氓气质1 小时前
Java中信号量(Semaphore):从本地到分布式
java·开发语言·分布式
怪奇云呼军1 小时前
G.711、Opus 和重采样会拖慢识别吗?闪电智能VoiceAgent 的音频入口怎么选
java·人工智能·python·算法·云计算·音视频
编程令我快乐1 小时前
maven部分构建参数讲解
java·maven
ZC跨境爬虫1 小时前
LeetCode 27. 移除元素(双指针详解 + Java Python 多解法对比)
java·python·leetcode
路溪非溪1 小时前
Python语言的执行流程总结
开发语言·python
民乐团扒谱机1 小时前
【超详解】量子克拉美罗下界QCRB:时延估计精度极限推导+MATLAB多场景绘图实战
开发语言·机器学习·matlab·量子力学·qcrb