正则表达式

前两天遇到一个需求,大概是这样:

有"放射性废物分类", "放射性物质", "放射性", "放射", "性" 这样一组词语,要在 这样一段话中匹配 ''关于发布《放射性废物分类》的公告,放射性物质是有害物质,放射元素会影响人的医生",要求如果长的包含短的只匹配长的,比如放射性包含放射和性,在放射性物质中只匹配放射性,匹配到的要前后加<em></em>

实现这样的功能就想到了正则表达式,下面先了解简单的正则语法

1.正则表达式介绍

正则表达式(Regular Expression),通常简称为"正则"或"Regex",是⼀种⽤于描述字符串模式 的表达式。它是由字符和运算符组成的⽂本模式,⽤于匹配、查找或替换⽂本中的字符序列。

主要功能 :

匹配⽂本模式; 查找和替换 ;数据提取 ; 表单验证 ; ⽂本处理⼯具

2.正则表达式语法

正则表达式(正则)的语法由⼀系列字符和操作符组成,⽤于定义字符串的模式。以下是⼀些常⻅ 的正则表达式语法元素:

2.1字⾯字符

普通字符: ⼤多数字符表示它们⾃身。例如,字⺟和数字⼤多直接匹配⾃身。

2.2元字符

  • .(点):

    匹配除换⾏符之外的任意字符。 a.b // 匹配 "aab"、"axb"、"a@b" 等

  • ^: 匹配字符串的开头。

    ^abc // 匹配以 "abc" 开头的字符串

  • $: 匹配字符串的结尾。

    xyz$ // 匹配以 "xyz" 结尾的字符串

  • \d \D 匹配⼀个数字或⾮数字

  • \n 匹配换⾏符

  • \s \S 匹配空⽩字符 或 ⾮空⽩字符

  • \w \W 匹配任何单词 或 ⾮单词 [A-Za-z0-9_]

2.3 字符类

...\]: 匹配⽅括号内的任何字符 [aeiou] // 匹配任何⼀个元⾳字⺟ \^ 表示取反,匹配不在⽅括号内的任何字符。 [^0-9] // 匹配任何⾮数字字符 ### 2.4量词 * \*: 匹配零次或多次前⾯的元素。 a* // 匹配 "a"、"aa"、"aaa" 等 * +: 匹配⼀次或多次前⾯的元素。 b+ // 匹配 "b"、"bb"、"bbb" 等 * ?: 匹配零次或⼀次前⾯的元素。 c? // 匹配 "c" 或空字符串 * {n}: 匹配恰好 n 次前⾯的元素。 d{3} // 匹配 "ddd" * {n,}: 匹配⾄少 n 次前⾯的元素。 e{2,} // 匹配 "ee"、"eee"、"eeee" 等 * {n,m}: 匹配⾄少 n 次且不超过 m 次前⾯的元素。 f{2,4} // 匹配 "ff"、"fff"、"ffff" 这些元素只是正则表达式语法的⼀部分,正则表达式还有许多⾼级特性和选项,具体取决于⽀持正 则表达式的⼯具或语⾔。学习正则表达式通常需要不断练习和实践,逐渐掌握其强⼤的⽂本匹配和 处理能⼒ ## 3.正则表达式⾼级特性 3.1 转义字符 \\: 转义字符,⽤于匹配元字符本身。 \. // 匹配句点字符 "." \? // 匹配? \+ // 匹配+ \* // 匹配* 3.2分组和捕获 (...): 创建⼀个分组,可以对其应⽤量词。 (abc)+ // 匹配 "abc"、"abcabc" 等 group(1) 可以获取 (?:...): ⾮捕获分组,不捕获匹配的内容。 (?:ab)+ // 匹配 "ab"、"abab" 等,group(1) 获取不到 3.3 零宽断⾔ (?=...): 正向肯定预查,匹配在某些内容之前的位置。 a(?=b) // 匹配 "a",但仅当其后⾯跟着"b" (?!...): 正向否定预查,匹配不在某些内容之前的位置。 x(?!y) // 匹配 "x",但仅当其后⾯不跟着 "y" (?\<=...): 反向肯定预查,匹配在某些内容之后的位置。 (?<=a)b // 匹配 "b",但仅当其前⾯是 "a" (?\Example"; Pattern pattern = Pattern.compile("a\\s*=\\s*\"[^\"]+\""); Matcher matcher = pattern.matcher(text); while (matcher.find()) { System.out.println(matcher.group()); } } 结果: text="value" ## 6.实现问题功能 ```java public class KeywordHighlighter { public static void main(String[] args) { // 给定的一段话 String text = "关于发布《放射性废物分类》的公告,放射性物质是有害物质,放射元素会影响人的医生"; // 关键词列表,按长度降序排列 String[] keywords = {"放射性废物分类", "放射性物质", "放射性", "放射", "性"}; // 调用方法进行匹配和高亮 String highlightedText = replaceKeywords(text, keywords); // 打印结果 System.out.println(highlightedText); } public static String replaceKeywords(String text, String[] keywords) { // 按长度降序排序关键词 Arrays.sort(keywords, (a, b) -> b.length() - a.length()); // 构建正则表达式 StringBuilder patternBuilder = new StringBuilder(); for (String keyword : keywords) { if (patternBuilder.length() > 0) { patternBuilder.append("|"); } patternBuilder.append(Pattern.quote(keyword)); } // 编译正则表达式 Pattern pattern = Pattern.compile(patternBuilder.toString()); Matcher matcher = pattern.matcher(text); // 替换匹配到的关键词 StringBuffer sb = new StringBuffer(); while (matcher.find()) { matcher.appendReplacement(sb, "" + matcher.group() + ""); } matcher.appendTail(sb); return sb.toString(); } } ``` 代码解释 > 1.给定的一段话: > > String text = "关于发布《放射性废物分类》的公告,放射性物质是有害物质,放射元素会影响人的医生";:定义了一段文本。 > > 2.关键词列表: > > String\[\] keywords = {"放射性废物分类", "放射性物质", "放射性", "放射", "性"};:定义了一个关键词列表。 > > 3.按长度降序排序关键词: > > Arrays.sort(keywords, (a, b) -\> b.length() - a.length());:按关键词长度降序排序,确保长词优先匹配。 > > 4.构建正则表达式: > > StringBuilder patternBuilder = new StringBuilder();:创建一个 StringBuilder 对象来构建正则表达式。 > > for (String keyword : keywords):遍历关键词列表,将每个关键词添加到正则表达式中。 > > Pattern.quote(keyword):对关键词进行转义,防止特殊字符影响正则表达式。 > > 5.编译正则表达式: > > Pattern pattern = Pattern.compile(patternBuilder.toString());:编译正则表达式。 > > Matcher matcher = pattern.matcher(text);:创建一个 Matcher 对象,用于在文本中查找匹配项。 > > 6.替换匹配到的关键词: > > StringBuffer sb = new StringBuffer();:创建一个 StringBuffer 对象,用于存储替换后的文本。 > > while (matcher.find()):遍历所有匹配项。 > > matcher.appendReplacement(sb, "\" + matcher.group() + "\");:将匹配到的关键词替换为带 \ 标签的高亮文本。 > > appendReplacement:从上次替换的位置到这次替换位置之间的字符串加上替换字符串一起追加到StringBuffer里 > > matcher.appendTail(sb);:将剩余的文本追加到 StringBuffer 中。 > > 打印结果: > > System.out.println(highlightedText);:打印高亮后的文本。 > > 关于发布《\放射性废物分类\》的公告,\放射性物质\是有害物质,\放射\元素会影响人的医

相关推荐
_extraordinary_27 分钟前
MySQL 库的操作 -- 增删改查,备份和恢复,系统编码
android·mysql·oracle
mutianhao102432 分钟前
SQLAlchemy 2.x 异步查询方法比较
python·mysql·sqlalchemy
User_芊芊君子32 分钟前
【金仓数据库征文】金仓数据库KingbaseES:在技术与人文交织中开拓信创未来
数据库·数据库平替用金仓·金仓数据库2025征文
傻啦嘿哟2 小时前
Python正则表达式:用“模式密码“解锁复杂字符串
linux·数据库·mysql
言之。3 小时前
别学了,打会王者吧
java·python·mysql·容器·spark·php·html5
辰哥单片机设计3 小时前
JW01三合一传感器详解(STM32)
数据库·mongodb
小刘同学++3 小时前
Qt使用 SQLite 数据库的基本方法
数据库·qt·sqlite
jack_xu5 小时前
高频面试题:如何保证数据库和es数据一致性
后端·mysql·elasticsearch
施嘉伟6 小时前
Oracle 11g RAC ASM磁盘组剔盘、加盘实施过程
数据库·oracle
橘猫云计算机设计7 小时前
springboot基于hadoop的酷狗音乐爬虫大数据分析可视化系统(源码+lw+部署文档+讲解),源码可白嫖!
数据库·hadoop·spring boot·爬虫·python·数据分析·毕业设计