正则表达式
正则表达式
1.概念
为什么学习正则表达式?
Java提供处理文本问题的技术,正则表达式(Regular Expression)是对字符串执行模式匹配的技术
2.了解正则表达式
package com.mf.study; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Author:mufan * @Date: 2022/06/11/10:06 * @Description: 体验正则表达式 */ public class Regexp_1 { public static void main(String[] args) { //编写爬虫,从百度页面得到如下文本 String content = "牟帆1997年农历6月29出生,当晚屋外电闪雷鸣,狂风骤起,刮了3000分钟。500次电闪雷鸣,显示这这个孩子的不凡!"; //1. \d表示任意字符 String regStr = "(\\d\\d)(\\d\\d)"; //2.创建模式对象(正则表达式) Pattern compile = Pattern.compile(regStr); //3.创建匹配器 Matcher matcher = compile.matcher(content); //4.开始匹配 /** * matcher.find() 完成任务 * 1. 根据指定的规则,定位满足规则的子字符串(比如1997) * 2.找到后,将 子字符串的开始的索引记录在 matcher 对象中 int[] groups 属性中 * groups[0]=2;把 该子字符串的结束的索引+1的值 记录到groups[1]=6中 * 3. 同时记录oldLast值 字符串的结束的索引+1的值 即6;即下次执行find方法时,从oldLast的值4 开始匹配 * *分组:比如 (\d\d)(\d\d),正则表达式中有() 表示分组 * 例如:根据指定规则,定位满足规则的子字符串(比如(19)(97)) * (1)groups[0] = 2,把该子字符串的结束索引 +1 groups[1] = 6 * (2) 第一组()匹配到的子字符串:groups[2] = 2 ,groups[3] = 4 * (3)第二组()匹配到的子字符串:groups[4] = 4 , groups[5] = 6 * 更多组。。。 * * 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.根据 group[0]=2 和 group[1]=6 记录的位置。 从content中开始截取子字符串,并返回 * * 如果再次执行find方法,从6开始匹配 * * */ while(matcher.find()){ /* 如果匹配规则有分组 matcher.group(0)-----匹配到的子字符串 matcher.group(1)-----匹配到的子字符串的第一组 matcher.group(2)-----匹配到的子字符串的第二组 。。。。。不能越界 */ System.out.println("匹配出所有4个任意数字:"+matcher.group(0));//1997 3000 System.out.println("匹配到的第一组:"+matcher.group(1));//19 System.out.println("匹配到的第二组:"+matcher.group(2));//87 } } }
3.正则表达式的语法
(1)元字符
元字符按功能分为: (1)限定符 (2)选择匹配符 (3)分组组合和反向引用符 (4)特殊字符 (5)字符匹配符 (6)定位符
元字符的转义符:\
什么情况下会用到转义符:* + ( ) $ / \ ? [ ] ^
I 字符匹配符
符号 | 符号 | 示例 | 解释 | 匹配输入 |
---|---|---|---|---|
[ ] | 可接收的字符列表 | [efgh] | e、f、g、h中的任意一字符 | e、f、g、h |
[^] | 不可接收的字符列表 | [^abc] | 除a、b、c外任意一字符,包含数字和特殊字符 | d、#、2、... |
- | 连字符 | A-Z | 任意单个大写字母 | A、D、... |
. | 匹配除 \n 以外的任何字符 | a..b | 以 a 开头,b结尾,中间包括2个任意字符的长度为4的字符串 | asdb、a#sb、... |
\\d | 匹配单个数字字符,相当于[0-9] | \\d{3}(\\d) | 包含3个或4个字符串 | 231、3445 |
\\D | 匹配单个非数字字符,相当于[^0-9] | \\D(\\d)* | 以单个非数字字符开头,后接任意个数字字符串 | a122zsxz、#12dssd |
\\w | 匹配单个数字、大小写字母字符。相当于[0-9a-zA-Z] | \\d{3}\\w | 以3个数字字符开头,长度为7的数字字母字符串 | 234abcd、12345Pe |
\\W | 匹配单个非数字、大小写字母字符,相当于[^0-9a-zA-Z] | \\W+\\d | 以至少一个非数字字母字符串开头,两个数字字符字符串结尾 | #29、#@……45 |
Java 正则表达式默认是区分到小写
不区分大小写第一种方法:
(?i)abc 表示abc都不区分大小写
a(?i)bc 表示bc不区分大小写
a((?i)b)c 表示b不区分大小写
不区分大小写第二种方法:
//创建Pattern对象时,表示匹配对象时字母是不区分大小写的 Pattern compile = Pattern.compile(regexp,Pattern.CASE_INSENSITIVE);
案例
package com.mf.study; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Author:mufan * @Date: 2022/06/11/9:50 * @Description: 演示字符匹配的使用 */ public class Test { public static void main(String[] args) { String content = "a11c8abc"; // String regexp = "[a-z]";//匹配 a-z 任意一个字符 // String regexp = "[A-Z]";//匹配 A-Z 任意一个字符 // String regexp = "abc";//匹配 abc 字符串(默认区分大小写) // String regexp = "(?i)abc";//匹配 abc 字符串(不区分大小写) // String regexp = "[0-9]";//匹配 0-9 任意一个字符 // String regexp = "[^a-z]";//匹配 不在 a-z 任意一个字符 // String regexp = "[^0-9]";//匹配 不在 0-9 任意一个字符 // String regexp = "[abc]";//匹配 在a、b、c中 任意一个字符 // String regexp = "[^abc]";//匹配 不在a、b、c中 任意一个字符 // String regexp = "\\w";//匹配 字母、数字、下划线 任意一个字符 // String regexp = "\\W";//匹配 除字母、数字、下划线之外 任意一个字符 // String regexp = "\\s";//匹配 空白字符(空格,制表符等) 任意一个字符 // String regexp = "\\S";//匹配 除空白字符(空格,制表符等)以外 任意一个字符 String regexp = ".";//匹配 \n之外的所有字符,如果匹配.本生要用转义字符 \\. Pattern compile = Pattern.compile(regexp); Matcher matcher = compile.matcher(content); while(matcher.find()){ System.out.println("匹配到:"+matcher.group(0));//a c } } }
II 选择匹配符
符号 | 符号 | 示例 | 解释 | 匹配输入 |
---|---|---|---|---|
| | 匹配“|”之前或之后的表达式 | ab|cd | ab|cd | ab、cd |
package com.mf.study; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Author:mufan * @Date: 2022/06/11/14:13 * @Description: 选择匹配符 */ public class Test1 { public static void main(String[] args) { String content = "timo 提莫 提 莫"; String regexp = "ti|莫"; //创建Pattern对象 Pattern compile = Pattern.compile(regexp); //创建匹配器 Matcher matcher = compile.matcher(content); while(matcher.find()){ System.out.println("找到:"+matcher.group(0)); } } }
III 限定符
符号 | 含义 | 示例 | 说明 | 匹配输入 |
---|---|---|---|---|
* | 指定字符重复0次或n次(无要求) | (abc)* | 仅包含任意个abc的字符串,等效于\w* | abc、sdsad |
+ | 指定字符重复1次或n次(至少一次) | m+(abc)* | 至少一个m开头,后接任意个abc字符串 | m、mabc、msdsabc、msdsftabcabc |
? | 指定字符重复0次或1次(最多1次) | m+abc? | 至少一个m开头,后接最多一个abc字符串 | m、mabc、msdsabc |
只能输入n个字符 | [abcd] | 由a、b、c、d中字母组成任意长度为3的字符串 | abc、dbc、adc | |
指定至少n个匹配 | [abcd] | 由abcd中字母组成的任意长度不小于3的字符串 | aab、bdc、aabdc | |
指定至少 n 个但不多于 m 个匹配 | [abcd] | 由abcd中字母组成的任意长度不小于3,不大于5的字符串 | abc、abcd、aaaa、bcdab |
package com.mf.study; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Author:mufan * @Date: 2022/06/11/14:36 * @Description:演示限定符的使用 */ public class Test2 { public static void main(String[] args) { String content ="11111111333243"; // String regexp = "a{3}";// 表示匹配 aaa 的字符 // String regexp = "1{4}";// 表示匹配 1111 的字符 // String regexp = "\\d{2}";// 表示匹配 2位任意字符串 // String regexp = "a{3,4}";// 表示匹配 aaa 或 aaaa (贪婪匹配,尽量匹配多的) // String regexp = "\\d{2,5}";// 表示匹配 2-5位数字字符串 (贪婪匹配,尽量匹配多的) // String regexp = "1+";// 表示匹配 一个1 或 多个 1 // String regexp = "1*";// 表示匹配 0个1 或 多个 1 String regexp = "a1?";// 表示匹配 a 或 a1 Pattern compile = Pattern.compile(regexp); Matcher matcher = compile.matcher(content); while(matcher.find()){ System.out.println("找到:"+ matcher.group(0)); } } }
IIII 定位符
符号 | 含义 | 示例 | 说明 | 匹配输入 |
---|---|---|---|---|
^ | 指定起始字符 | [1]+[a-z]* | 以至少1个数字开头,后接任意个小写字母的字符串 | 123、6aa、555edf |
$ | 指定结束字符 | [2]\\-[a-z]+$ | 以1个数字开头后连接字符"-",并以至少1个小写字母结尾的字符串 | 1-a |
\\b | 匹配目标字符串的边界 | han\\b | 这里说的字符串的边界指的是子串间有空格,或者是目标字符串的结束位置 | |
\\B | 匹配目标字符串的非边界 | han\\B | 和\b的含义刚刚相反 |
package com.mf.study; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Author:mufan * @Date: 2022/06/11/15:16 * @Description:演示定位符的使用 */ public class Test3 { public static void main(String[] args) { String content = "123abc cd bc"; //以至少1个数字开头,后接任意个小写字母的字符串 // String regexp = "^[0-9]+[a-z]*"; //至少1个数字开头,必须以至少一个小写字母结束 // String regexp = "^[0-9]+[a-z]+$"; // String regexp = "c\\b"; //匹配边界(该字符串最后,或空格后子字符串的最后)c ------c c String regexp = "c\\B"; //匹配边界(该字符串开头,或空格后子字符串的开头)c ------c Pattern compile = Pattern.compile(regexp); Matcher matcher = compile.matcher(content); while(matcher.find()){ System.out.println("找到:"+matcher.group(0)); } } }
IIIII 分组
常用分组构造形式 | 说明 |
---|---|
() | 非命名捕获 |
(? |
命名捕获 |
package com.mf.study; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @Author:mufan * @Date: 2022/06/11/15:38 * @Description:分组 */ public class Test4 { public static void main(String[] args) { String content = "moufan s3w423 df55f4fan"; String regexp = "(?<g1>\\d)(\\d)";//匹配2位数 Pattern compile = Pattern.compile(regexp); Matcher matcher = compile.matcher(content); while(matcher.find()){ System.out.println("找到:"+matcher.group(0)); System.out.println("通过编号取第一组:"+matcher.group(1)); System.out.println("通过组名获取第一组:"+matcher.group("g1")); System.out.println("第二组:"+matcher.group(2)); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异