韩顺平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
* 北京
*/
相关推荐
Q26433650236 分钟前
【有源码】基于SpringBoot+Vue的居民健康体检与慢病干预管理系统-面向智慧医疗的体检预约与健康知识服务平台
java·vue.js·spring boot·mysql·毕业设计·javaweb·课程设计
事圆则缓10 分钟前
Kotlin 集合与序列:给页面一份清楚的数据
开发语言·windows·kotlin
事圆则缓12 分钟前
Kotlin 异步与并发:从一次搜索请求走到状态流
android·开发语言·kotlin
从小白到软工25 分钟前
4-3 项目-学生成绩管理系统(上)
c语言·开发语言·数据结构·经验分享·ai编程
悠仁さん28 分钟前
非类型模板参数的特化与偏特化
java·数据结构·算法
鬼手点金35 分钟前
上下文:Agent 的眼睛
java·前端·人工智能·git·深度学习
外收内放44 分钟前
Python基础语法练习题(72)
开发语言·python
无忧.芙桃1 小时前
C++语言原理与实践(十三):stack、queue 和 priority_queue的介绍与使用
开发语言·c++·栈·队列
171320330计算机毕设编程1 小时前
计算机毕业设计 基于Hadoop的新能源汽车发展前景分析 LW PPT
java·大数据·hadoop·python·算法·随机森林·线性回归