正则表达式
反斜杠详解
1、字符串、正则表达式的反斜杠功能
(1)代表特殊字符
(2)代表转义
2、字符串、正则表达式的处理是分离的
(1)字符串“\\\\”-> 正则表达式“\”:字符串“\\\\”转义出两个普通的反斜杠“\\”,“\\”在正则表达式中,转义出一个普通的反斜杠“\”
(2)字符串“\\”-> 正则表达式“\”:字符串“\\”转移出一个普通的反斜杠“\”,“\”在正则表达式中表示一个转义符
3、Java 正则表达式中,字符串“\” 代表其的转移符号 \
(1)用于检索某些特殊字符,使用 \转义
(2)需要转义符号的字符:. * + ( ) $ | ? [ ] ^ { } \
(3)[] 中带有需要转义的字符,不需要“\”转义
元字符分类
1、限定符
2、选择匹配符
3、分组组合和反向引用符
4、特殊字符
5、字符匹配符
6、定位符
字符匹配符 | 含义 | 例 |
[ ] | 可接收字符列表,表示其中的元素任意一个,不允许重复,重复字符视作一个字符 | [abb]:a、b 中的任一个字符 |
[^ ] | 不接收字符列表 | [^ab]:除 a、b 之外的任一字符 |
- | 连字符,搭配 [ ],不在 [ ] 中时,为普通字符 | [a-z]:任意单个小写字母 |
. | 匹配单个除 \n 以外的任何字符 | a..b:以 a 开头,b 结尾,中间 2 个任意字符,长度为 4 的字符串 |
"\d" | 匹配单个数字字符 | <=> [0-9] |
"\D" | 匹配单个非数字字符 | <=> [^0-9] |
"\w" | 匹配单个数字、大小写字母、下划线 | <=> [0-9a-zA-Z_] |
"\W" | 匹配单个非数字、非大小写字母、非下划线 | <=> [^0-9a-zA-Z_] |
"\s" | 匹配单个任何空白字符 | |
"\S" | 匹配任何非空白字符 |
选择匹配符 | 含义 | 例 |
| | 匹配“|”之前或之后的正则表达式 | a|b:匹配 a 或 b |
限定符 | 含义 | 说明 |
* | 指定字符重复 0 或 n 次 | 组合前面字符或正则表达式进行匹配 |
+ | 指定字符重复 1 或 n 次 | |
? | 指定字符重复 0 或 1 次 | |
{n} | 只能输入 n 个字符 | |
{n,} | 指定至少 n 个字符匹配 | |
{n,m} | 指定至少 n 个,但不多于 m 个字符匹配 |
1、Java 默认为贪婪机制,会尽可能多的匹配
2、当 ? 在其他限定符之后,变为非贪婪匹配,会尽可能少的匹配
定位符 | 含义 | 说明 |
^ | 指定起始字符,位于起始字符之前,匹配输入字符串的开始位置 | 默认匹配整个字符串的首、尾 |
$ | 指定结束字符,位于结束字符之前,匹配输入字符串的结束位置 | |
"\b" | 匹配目标字符串的边界,边界指子串之间有空格或目标字符串结束位置 | 位于匹配字符串之前,表示为子串的开始;位于匹配字符串之后,表示为子串的结尾 |
"\B" | 匹配目标字符串的非边界 | 匹配不关心是子串的开头还是结尾,所以位置并不重要 |
捕获分组
1、(pattern) 非命名捕获:捕获匹配的子字符串
(1)编号为 0 的第一个捕获是由整个正则表达式模式匹配的文本
(2)其他捕获结果根据左括号的顺序从 1 开始自动编号
2、(?<name>pattern) 命名捕获:将匹配子字符串捕获到一个组名或编号名中
(1)用于 name 的字符串不能含有任何标点符号,且不能以数字开头
(2)可以使用 '' 代替 <>
非捕获分组
1、匹配 pattern 但不捕获该匹配表达式,不储存分组,即在之后的匹配不能使用分组
2、种类
(1)(?:pattern)
(2)(?=pattern)
(3)(?!pattern)
3、例:a1a2a3a4
(1)a(?;1|2|3|4):等价于 a1|a2|a3|a4,匹配:a1a2a3a4
(2)a(?=1|2):匹配:a(a1中的a)a(a2中的a)
(3)a(?!=1|2):匹配:a(a3中的a)a(a4中的a)
Pattern 类
1、Pattern 类没有构造器
2、Pattern 对象是正则表达式对象
3、接收 String 正则表达式,返回一个 Pattern 对象
public static Pattern compile(String regex)
4、接收 String 正则表达式、标志,返回一个 Pattern 对象
public static Pattern compile(String regex, int flags)
5、flags 是 Pattren 类中常量
(1)可以传入 Pattern 的 compile 方法
(2)可以直接嵌入正则表达式中
(3)嵌入式标志表达式 (?d),启用 Unix 行模式,只有 \n 才被认作一行的中止,并且与 . ^ $ 进行匹配,
public static final int UNIX_LINES = 0x01;
(4)嵌入式标志表达式 (?i) 启用不区分大小写的匹配,仅匹配 US-ASCII 字符集中的字符
public static final int CASE_INSENSITIVE = 0x02;
(5)嵌入式标志表达式 (?x) 允许空格和注释格式,忽略空格,并且以 # 开头的嵌入式注释将被忽略
public static final int COMMENTS = 0x04;
(6)嵌入式标志表达式 (?m) 启用多行模式,^ 和 ? 将逐次匹配每一行的行首、行尾,默认情况下,仅匹配整个输入序列的开头和结尾
public static final int MULTILINE = 0x08;
(7)启用模式的文字解析,没有嵌入的标志字符,该 Pattern 对象的输入字符串将被视为文字字符序列,输入序列中的元字符 / 转义字符将没有任何特殊含义
public static final int LITERAL = 0x10;
(8)嵌入式标志表达式 (?s) 启用点阵模式,. 将匹配任何字符,包括 \n,默认情况下 . 不匹配 \n
public static final int DOTALL = 0x20;
(9)嵌入式标志表达式 (?u) 启用不区分大小写的匹配,仅匹配 Unicode 字符集中的字符
public static final int UNICODE_CASE = 0x40;
6、指定正则表达式,并匹配给定的输入
public static boolean matches(String regex, CharSequence input) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
return m.matches();
}
(1)m.matches() 是 Matcher 类的 matches 方法,等价于正则中前加 ^,后加 $
(2)该方法等价于: Pattern.compile(regex).matcher(input).matches();
7、返回一个 Matcher 对象,使用 Pattern 对象中的正则表达式,与 input 匹配
public Matcher matcher(CharSequence input)
Matcher 类
1、Matcher 对象需要调用 Pattern 的 matcher 方法取得
2、返回整个文本匹配后的最后一个字符索引
public int end()
3、返回给定 group 组捕获的子序列的最后一个字符的索引,end(0) 等价于 end()
public int end(int group)
4、返回给定 name 捕获子序列的最后一个字符索引
public int end(String name)
5、尝试找到匹配模式的输入序列的下一个子序列
public boolean find()
6、重新设置该匹配器,然后尝试从指定的索引开始找到匹配模式的输入序列的下一个子序列
public boolean find(int start)
7、返回与匹配的输入子序列
public String group()
8、返回给定 group 组捕获的输入子序列,group(0) 等价于 groiup()
public String group(int group)
9、返回给定 name 捕获的输入子序列
public String group(String name)
10、将整个文本与模式进行匹配,要求整个字符串匹配,等价于正则中前加 ^,后加 $
public boolean matches()
11、将输入序列从开头开始与模式匹配,不要求整个字符串匹配
public boolean lookingAt()
12、将与模式匹配的输入序列的每个子序列替换为给定的替换字符串,不影响原 String
public String replaceAll(String replacement)
13、将与模式匹配的输入序列的第一个子序列替换为给定的替换字符串,不影响原 String
public String replaceFirst(String replacement)
14、返回上一个匹配的起始索引
public int start()
15、返回给定 group 组在上一个匹配操作期间捕获的子序列的开始索引
public int start(int group)
16、返回给定 name 捕获的子序列的初始索引
public int start(String name)
17、默认值为 -1
int[] groups;
find() 解析
1、根据正则,定位满足正则表达式的子字符串,子字符串的索引会记录到 int[] groups
(1)groups[0] = 子字符串的开始字符索引
(2)groups[1] = 子字符串的结尾字符索引 + 1
2、若正则表达式存在分组,以第一个分组为例
(1)groups[2] = 第一个分组字符串的开始字符索引
(2)groups[3] = 第一个分组字符串的结尾字符索引 + 1
3、同时 this.oldlast = 子字符串的结尾字符索引 + 1
4、下次调用 find(),就从 oldlast 索引开始,且会把 groups 中的索引清空
group() 解析
1、根据 groups 中的索引,从整个文本截取 [groups[group * 2], groups[group * 2 + 1]) 字符串并返回,注意开闭区间
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
CharSequence getSubSequence(int beginIndex, int endIndex) {
return text.subSequence(beginIndex, endIndex);
}
2、group(0) 表示匹配的整个子字符串,group(1) 表示匹配子字符串的第一个分组字符串,依次类推
3、正则表达式中第一个 () 为第一组,groups[2] = 第一组字符串开始索引,groups[3] = 第一组字符串结尾索引 + 1,依此类推
子表达式
1、分组:一个 () 看作一个分组 / 子表达式
2、捕获
(1)把正则表达式分组匹配的内容,保存到内存中以数字编号或显示命名的组里
(2)组 0 代表整个正则表达式,从左至右以 ( 为标志,第一个出现分组的组号为 1
3、反向引用:() 内容被捕获后,可在该 () 后面使用
(1)内部反向引用:在正则表达式内部使用,“\分组组号”
(2)外部反向引用:在正则表达式外部使用,“$分组组号”,可用于文本去重
(3)例
String content = Pattern.compile("(.)\\1+").matcher("111222333").replaceAll("$1");
String 类中使用正则表达式
1、替换
public String replaceAll(String regex, String replacement)
2、判断,等价于 Pattern.matches(regex, str)
public boolean matches(String regex)
3、分割
(1)等价于 split(regex, 0)
public String[] split(String regex)
(2)limit > 0,调用 limit - 1 次,且数组长度 <= limit;limit = 0,调用尽可能多次,含开头空字符串,不含结尾空字符串;limit < 0,调用尽可能多次,包含开头空字符串、结尾空字符串
public String[] split(String regex, int limit)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战