正则表达式

正则表达式

1.概念

  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 定位符

符号 含义 示例 说明 匹配输入
^ 指定起始字符 +[a-z]* 以至少1个数字开头,后接任意个小写字母的字符串 123、6aa、555edf
$ 指定结束字符 \\-[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));
}
}
}

  1. 0-9 ↩︎

  2. 0-9 ↩︎

posted @   snail05  阅读(60)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示