简介: 本文会教你如何写出自己想要的正则表达式,作者不会排版文章,所有子章节都以代码块的 形式。
***********************************************************************************************************
目录
1.相关术语:
'表达式引擎'
1.表达式引擎是由Pattern类和Matcher类构成的。
2.表达式引擎的作用如下:
作用1: 查找文本内的目标字符串。
作用2: 对文本内的目标字符串进行提取、替换。
'解析文本'
我们将引擎查找文本内容中的目标字符串的过程称为解析文本。
'操作'
操作指的是表达式引擎对目标字符串进行提取或替换。
'文本'
被引擎查找目标字符串的字符串就是文本。
'正则表达式'
正则表达式是引擎查找文本中目标字符串的依据。
'待筛选字符串'
文本中满足正则表达式每个实意字符匹配策略的子串就是待筛选字符串。
'目标字符串'
待筛选字符串若满足正则表达式中的筛选基点,那么它就是目标字符串,反之不被视为目标字符串。
'字符列表'
字符列表是自定义元字符的定义格式。
'实意字符'
在解析文本时,引擎得为表达式中具有匹配策略的字符匹配文本中的字符。
这些拥有匹配策略的字符就是实意字符。
'自定义定位符'
自定义定位符也叫断言或预搜索或非捕获分组,但这些都不如自定义定位符来得好理解。
2.转义字符:
'转义字符的基本概念'
(1)字符转义指的是使用反斜杠来改变某个字符原本的含义,改变含义后的字符就被称为转义字符,注意!被转
义的字符与反斜杠一起只被算作一个字符!
例: n原先表示字符n,而\n则表示换行符。
(2)转义字符可以在字符或字符串中定义。
例: char c1 = '\n'; String str = "\n";
(3)常见通过反斜杠转义的字符: \n: 换行符。
\t: 制表位。
\r: 回车符
\': 表示一个单引号。
\": 表示一个双引号。
\.: 表示一个点号。
\\: 表示一个反斜杠。
(4)如果反斜杠转义的字符不是转义字符,则编译报错。
(5)拓展字符: 当我们在字符串中要表示0~65535之外的字符时,可以采用代理对的形式来表示它,代理对分
为左代理和右代理,且它们都是转义字符。
"\uD83D\uDE0A"输出时就表示1个😊符号。
若想查看更多有趣的拓展字符,可查看Unicode字符集对照表:https://symbl.cc/en/
'说明': \uD83D和\uDEOA是两个字符,只有在输出时候才会组成一个拓展字符,不输出时当作
两个字符运算。
例如"\uD83D\uDE0A".length()等于2。
**************************************************************************************
'知识拓展'
除语言外,不同操作系统上的换行符是不太一样的,系统旗下的软件例如windows 系统下的dos、记事本等
软件字符显示时使用的都是本系统对应的换行符作为换行符的,所以我们将换行符写入一个文件时,应写入文
件系统对应的换行符,不然无法达成换行效果。
Windows系统换行符: \r\n。
Unix/Linux系统换行符: \n。
MacOs系统换行符: 早期系统版本是\r,如今使用\n。
'补充说明': 当我们往windows系统下的软件例如记事本内写入换行符时,只需要写入\n即可,因为windows
系统会将其转换改为\r\n写入记事本内。
当读取记事本的换行符时,windows系统也会将\r\n自动转换为\n被读取。
3.正则表达式的基本概念:
'正则表达式的基本概念'
1.正则表达式这一章节我们要学习如下3点。
目标1: 引擎解析文本时,底层是如何实现查找到每个目标字符串的。
目标2: 如何写出各个业务场景下的正则表达式。
目标3: 组成表达式引擎的两个类: Pattern类和Matcher类。
2.我们在书写每一个实意字符时,需要考虑如下两个因素。
因素1: 该字符的匹配策略。
因素2: 该字符所代表字符的是什么。
3.引擎在解析文本时,引擎会将文本和正则表达式中的左右代理对仅视为一个字符。
'说明1': 拓展字符举例: 😊...更多的可看知识点-转义字符章节。
'说明2': 左代理和右代理是由两个转义字符组成的,但在引擎解析文本时会被视为同一个字符。
****************************************************************************************
'不同的编码体验'
在idea平台上编写正则表达式与在其它IDE或命令台界面上编写正则表达式的体验不同。
在idea上编写正则表达式时,如果运行时该正则表达式会导致'模式语法异常',那么idea会在编写阶段就即时提
醒开发者,提示信息通常以红色波浪线的形式出 现在错误代码的下方。这能更好的帮助开发者及时发现并纠正
错误。
但如果我们不管idea的提示信息,任由它报错,尽管编译时不会产生编译错误,但运行时idea会变的与其它IDE
或命令台界面一样抛出'模式语法异常'。
总结: IDEA提供了在编写正则表达式阶段即时检测正则表达式中语法错误的功能,这是其它IDE与命令台没有
的。
4.引擎解析文本的底层:
'前言': 当我们使用引擎中提供的方法来对文本内的目标字符串进行操作时,引擎就会开始解析文本。
'解析文本的大致步骤'
第1步: 忽略正则表达式中所有拥有筛选基点的元字符。
第2步: 根据正则表达式中的每个实意字符来匹配出待筛选字符串。
第3步: 将满足所有筛选基点的待筛选字符串筛选成目标字符串。
第4步: 对文本内的目标字符串进行操作。
5.实意字符的四种匹配策略:
(1)固定模式:
'固定模式的基本概念'
1.固定模式分为基本固定模式与量词固定模式。
2.基本固定模式的基本概念:
(1)在正则表达式中,如果实意字符没有被量词修饰,那么它默认是基本固定模式。
(2)表达式引擎是如何为基本固定模式的表达式字符匹配文本中字符的?
//该步骤只是大致的,仅供参考。
'答': 表达式引擎首先会从当前匹配点开始,为表达式字符匹配1个文本中该字符所代表的字符。
如果匹配成功,表达式引擎会按照下一个字符的匹配策略继续为下一个表达式字符匹配文本中的
字符。
如果匹配失败,表达式引擎会根据匹配点是否已到达文本内容末尾来做不同的操作。
(1)如果匹配点已到达文件内容末尾,那么此次操作结束。
(2)如果匹配点并没有到达文件内容的末尾,那么表达式引擎放弃当前匹配点,并将匹配点向后
移动一位,再根据正则表达式中每个字符的匹配策略逐个为表达式字符匹配文本内的字符。
3.量词固定模式的基本概念:
(1)在正则表达式中,如果实义字符被固定量词修饰,那么该实义字符的模式会变为量词固定模式。
'代指': 本节中的n代表固定量词的固定匹配数,用于增加笔记的可读性。
(2)表达式引擎是如何为量词固定模式的表达式字符匹配文本中字符的?
'答': 表达式引擎首先会从当前匹配点开始,为表达式字符匹配n个文本中该字符所代表的字符。
如果匹配成功,表达式引擎会按照下一个字符的匹配策略为下一个字符匹配文本中的字符。
如果匹配失败,表达式引擎会根据匹配点是否已到达文本内容末尾来做不同的操作。
(1)如果匹配点已到达文件内容末尾,那么此次操作结束。
(2)如果匹配点并没有到达文件内容的末尾,那么表达式引擎放弃当前匹配点,并将匹配点向后移
动一位,再根据正则表达式中每个字符的匹配策略逐个为表达式字符匹配文本内的字符。
(2)贪婪模式:
'贪婪模式的基本概念'
1.在正则表达式中,如果实意字符被贪婪量词修饰,那么该实意字符的匹配策略就会是贪婪模式。
'代指1': 本节n代指贪婪量词的最大匹配数,用于增加可读性。
'代指2': 本节m代指贪婪量词的最小匹配数,用于增加可读性。
2.表达式引擎是如何为贪婪模式的实意字符匹配文本中字符的?
//该步骤只是大致的,仅供参考。
'答': 表达式引擎首先会从当前匹配点开始,为表达式字符匹配n个文本中该字符所代表的字符,再根据后续
字符是否都能按照对应的匹配策略匹配成功来做不同的操作。
如果后续字符都能按照对应的匹配策略匹配成功,那么视为匹配成功,引擎再对该目标字符串进行相应
的操作例如提取或替换。
如果后续的字符只要有1个没按照对应的匹配策略匹配成功,那么发生回溯,引擎再尝试为其匹配n-1
个文本中该表达式字符所代表的字符。
往复如此,直至后续所有的字符都能按照对应的匹配策略匹配成功。
如果引擎为表达式字符匹配m个文本中该字符所代表的字符后,后续字符依旧出现匹配失败,表达式引
擎会根据匹配点是否已到达文本内容末尾来做不同的操作。
(1)如果匹配点已到达文件内容末尾,那么此次操作结束。
(2)如果匹配点并没有到达文件内容的末尾,那么表达式引擎放弃当前匹配点,并将匹配点向后移动一
位,再根据正则表达式中每个字符的匹配策略逐个为表达式字符匹配文本内的字符。
3.当贪婪量词的最小匹配数为0时,表达式引擎为表达式字符匹配文本内的字符可能会产生一些歧义。但实际写正
则表达式时,我们很少遇到贪婪量词最小匹配数为0的场景。
4.当真的遇到需要贪婪量词最小匹配数为0时,我们可以根据上面的概念结合现场实验然后推出自己想要的效果,
也可以上网查找。
(3)懒惰模式:
'懒惰模式的基本概念'
1.在正则表达式中,如果实意字符被懒惰量词修饰,那么该实义字符的模式会变为懒惰模式。
'代指1': 本节n代指懒惰量词的最大匹配数,用于增加可读性。
'代指2': 本节m代指懒惰量词的最小匹配数,用于增加可读性。
2.表达式引擎是如何为懒惰模式的表达式字符匹配文本中字符的?
//该步骤只是大致的,仅供参考。
'答': 表达式引擎首先会从当前匹配点开始,为表达式字符匹配m个文本中该字符所代表的字符,再根据后续
字符是否都能按照对应的匹配策略匹配成功来做不同的操作。
如果后续字符都能按照对应的匹配策略匹配成功,那么视为匹配成功,引擎再对该目标字符串进行相应
的操作例如提取或替换。
如果后续的字符只要有1个没按照对应的匹配策略匹配成功,那么发生回溯,引擎再尝试为其匹配m+1
个文本中该表达式字符所代表的字符。
往复如此,直至后续所有字符都能按照对应的匹配策略匹配成功。
如果引擎为表达式字符匹配n个文本中该字符所代表的字符后,后续字符依旧出现匹配失败,表达式引
擎会根据匹配点是否已到达文本内容末尾来做不同的操作。
(1)如果匹配点已到达文件内容末尾,那么此次操作结束。
(2)如果匹配点并没有到达文件内容的末尾,那么表达式引擎放弃当前匹配点,并将匹配点向后移动一
位,再根据正则表达式中每个字符的匹配策略逐个为表达式字符匹配文本内的字符。
3.当懒惰量词的最小匹配数为0时,表达式引擎为表达式字符匹配文本内的字符可能会产生一些歧义。但实际写正
则表达式时,我们很少遇到懒惰量词最小匹配数为0的场景。
4.当真的遇到需要懒惰量词最小匹配数为0时,我们可以根据上面的概念结合现场实验然后推出自己想要的效果,
也可以上网查找。
(2)占有模式:
'占有模式的基本概念'
1.在正则表达式中,如果实意字符被占有量词修饰,那么该实义字符的模式会变为占有模式。
'代指1': 本节n代指占有量词的最大匹配数,用于增加可读性。
'代指2': 本节m代指懒惰量词的最小匹配数,用于增加可读性。
2.表达式引擎是如何为占有模式的表达式字符匹配文本中字符的?
//该步骤只是大致的,仅供参考。
'答': 表达式引擎首先会从当前匹配点开始,为表达式字符匹配n个文本中该字符所代表的字符,再根据后续
字符是否都能按照对应的匹配策略匹配成功来做不同的操作。
如果后续字符都能按照对应的匹配策略匹配成功,那么视为匹配成功,引擎再对该目标字符串进行相应
的操作例如提取或替换。
如果后续的字符只要有1个没按照对应的匹配策略匹配成功,那么不回溯,表达式引擎会根据匹配点是
否已到达文本内容末尾来做不同的操作。
(1)如果匹配点已到达文件内容末尾,那么此次操作结束。
(2)如果匹配点并没有到达文件内容的末尾,那么表达式引擎放弃当前匹配点,并将匹配点向后移动一
位,再根据正则表达式中每个字符的匹配策略逐个为表达式字符匹配文本内的字符。
3.当占有量词的最小匹配数为0时,表达式引擎为表达式字符匹配文本内的字符可能会产生一些歧义。但实际写正
则表达式时,我们很少遇到懒惰量词最小匹配数为0的场景。
4.当真的遇到需要占有量词最小匹配数为0时,我们可以根据上面的概念结合现场实验然后推出自己想要的效果,
也可以上网查找。
6.元字符:
(1)元字符的基本概念:
'元字符的基本概念'
(1)元字符指的是在正则表达式中具有特殊含义的字符,如果元字符不在正则表达式中,那么它仅代表着它的
字面含义。
(2)元字符转义:
1.元字符转义指的是通过在正则表达式中使用双反斜杠来改变某个字符原本的字面含义,转义后的字符就
可以称为元字符。
需要注意的是,双反斜杠加被转义的字符一起只被引擎视为1个字符。
2.元字符转义的语法只在正则表达式中有效,在其它字符串或字符中这种转义写法不会导致元字符转义,
仅会按照字面含义解释。
3.如果元字符转义的字符无法与双反斜杠构成元字符,那么编译时不报错,但运行时会抛出'模式语法异
常'。
(3)每个元字符书写在正则表达式的不同位置代表的含义也可能会不同,我们在写元字符时也需要明确知晓它
写在所处位置是什么含义。
(4)我们在写不是一个字符组成的元字符时,要写就写一个整体,写单个字符的情况可能造成某些歧义。
(2)字符匹配符:
字符匹配符一览表:
'字符匹配符-系列1'
(1)\\.
(2)\\^
(3)\\?
(4)\\+
(5)\\-
(6)\\*
(7)\\$
(8)\\|
(9)\\\\
'字符匹配符-系列2'
(10)\\r
(11)\\n
(12)\\f
(13)\\t
(14)\\v
'字符匹配符-系列3'
(15)\\[
(16)\\]
(17)\\{
(18)\\}
(19)\\(
(20)\\)
'字符匹配符-系列4'
(21).
(22)\\d
(23)\\D
(24)\\w
(25)\\W
(26)\\s
(27)\\S
字符匹配符详解:
'字符匹配符-系列1'
(1)\\. 特殊含义: 它仅代表1个点字符。
字面含义: 它代表1个反斜杠和1个点字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(2)\\^ 特殊含义: 它仅代表1个脱字符。
字面含义: 它代表1个反斜杠和1个脱字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(3)\\? 特殊含义: 它仅代表1个问号字符。
字面含义: 它代表1个反斜杠和1个问号字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(4)\\+ 特殊含义: 它仅代表1个加号字符。
字面含义: 它代表1个反斜杠和1个加号字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(5)\\- 特殊含义: 它仅代表1个连字符。
字面含义: 它代表1个反斜杠和1个连字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(6)\\* 特殊含义: 它仅代表1个乘号字符。
字面含义: 它代表1个反斜杠和1个乘号字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(7)\\$ 特殊含义: 它仅代表1个美元字符。
字面含义: 它代表1个反斜杠和1个美元字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(8)\\| 特殊含义: 它仅代表1个或字符。
字面含义: 它代表1个反斜杠和1个或字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(9)\\\\ 特殊含义: 它仅代表1个反斜杠字符。
字面含义: 它代表2个反斜杠字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
'字符匹配符-系列2'
(10)\\r 特殊含义: 它仅代表1个\r回车符。
字面含义: 它代表1个反斜杠和1个字母r的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(11)\\n 特殊含义: 它仅代表1个\n换行符。
字面含义: 它代表1个反斜杠和1个字母f的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(12)\\f 特殊含义: 它仅代表1个\f换页符。
字面含义: 它代表1个反斜杠和1个字母f的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(13)\\t 特殊含义: 它仅代表1个\t制表符。
字面含义: 它代表1个反斜杠和1个字母t的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(14)\\v 特殊含义: 它仅代表1个\v垂直制表符。
字面含义: 它代表1个反斜杠和1个字母v的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
'字符匹配符-系列3'
(15)\\[ 特殊含义: 它仅代表1个左方括号字符。
字面含义: 它代表1个反斜杠和1个左方括号字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(16)\\] 特殊含义: 它仅代表1个右方括号字符。
字面含义: 它代表1个反斜杠和1个右括号字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(17)\\{ 特殊含义: 它仅代表1个左花括号字符。
字面含义: 它代表1个反斜杠和1个左花括号字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(18)\\} 特殊含义: 它仅代表1个右花括号字符。
字面含义: 它代表1个反斜杠和1个右花括号字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(19)\\( 特殊含义: 它仅代表1个左圆括号字符。
字面含义: 它代表1个反斜杠和1个左圆括号字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(20)\\) 特殊含义: 它仅代表1个右圆括号字符。
字面含义: 它代表1个反斜杠和1个右圆括号字符的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
'字符匹配符-系列4'
(21). 特殊含义: 它可以代表除换行符之外的所有字符。
字面含义: 它代表1个点字符。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(22)\\d 特殊含义: 它可以代表数字字符、即数字0~9。
字面含义: 它代表1个反斜杠和字母d的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(23)\\D 特殊含义: 它可以代表\\d代表不了的字符。
字面含义: 它代表1个反斜杠和字母D的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(24)\\w 特殊含义: 它可以代表大小写字母、数字字符、下划线。
字面含义: 它代表1个反斜杠和字母w的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(25)\\W 特殊含义: 它可以代表\\w代表不了的字符。
字面含义: 它代表1个反斜杠和字母W的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(26)\\s 特殊含义: 它可以代表空白、制表符、换页符。
字面含义: 它代表1个反斜杠和字母s的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(27)\\S 特殊含义: 它可以代表\\s代表不了的字符。
字面含义: 它代表1个反斜杠和字母S的组合。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(3)选择匹配符:
'选择匹配符'
| 特殊含义: 它可以对正则表达式进行切割,一次切割会以选择匹配符字符为分割线,形成左右两个子正则
表达式。
当表达式引擎寻找文本中的目标字符串时,只要文本中子串能满足正则表达式中的1个子表达
式'每个字符的匹配策略',那么该子串就会被引擎认为是目标字符串。
字面含义: 表示一个竖线字符。
字面含义位置: 元字符失效区、字符列表内。
特殊含义位置: 非字面含义位置。
'说明1': 正则表达式可以被切割无数次。
'说明2': 子正则表达式的内容可以为"",它也是符合切割逻辑的。
'说明3': 同一正则表达式的子正则表达式内容可以重复,重复多少次可以。
(4)自定义元字符:
'自定义元字符的基本概念'
(1)自定义元字符是对字符匹配符的补充,它可以让我们定义自己的字符匹配符用于描述各种需要代表的字
符。
(2)自定义元字符的定义格式: "[列出字符..]"
我们可以在字符列表内使用如下3种写法列出自定义元字符需要代表的字符。
写法1: 将单个字符写入字符列表。
写法2: 将整个字符区间对应的字符写入字符列表内,例如[a-b]。
写法3: 将字符匹配符特殊含义所代表的字符写入字符列表内。
'细节1': 写法3中说的元字符也包括自定义元字符,但没人会嵌套写,因为没有多大意义。
'细节2': 这3种写法可以同时写在同一字符列表中,并且没有个数限制。
'细节3': 字符区间对应的字符指的是左字符码值至右字符码值对应Unicode码值区间的字符。
'细节4': 由这3种写法写入字符列表内的字符,就是字符列表所列出的字符。
'细节5': 字符列表内可以书写元字符失效区,使元字符变为字面含义。
当书写字符列表时要注意如下两种异常情况。
'异常情况1': 在字符列表中书写字符区间时,需要注意连字符的左码值必须小于等于右字符的码值,
如果不满足编译不报错,但运行时会抛出'模式语法异常'。
'异常情况2': 字符列表所列出的字符数量不能为0,如果为0编译不报错,但运行时会抛出'模式语法异
常'。
(3)书写[、]、[]这三个元字符的相关细节:
1.书写[时,需要注意它是构成字符列表的基础元字符,它不应该单独于]存在,单独存在会导致不可预
期的一些错误,遵守即可。
2.书写]时,需要注意它是构成字符列表的基础元字符,它不应该单独于[存在,单独存在会导致不可预
期的一些错误,遵守即可。
3.[]可以嵌套写在另一个字符列表中,但意义不大,不推荐。
4.将[、]、[]这三者写在元字符失效区内,会使其变为字面含义。
'拓展写法'
写法: 将]书写在字符列表开头时,它会使自定义元字符代表它。
(4)在字符列表中会被触发特殊含义的元字符:
'连字符- 码值45'
特殊含义: 它不代表任何字符,它会作为字符区间的连字符。
字面含义: 它代表1个连字符。
字面含义位置: 非特殊含义位置。
特殊含义位置: 当它在字符列表内,且左右位置都有字符时,会触发它的特殊含义。
'如何在字符列表写入它的字面含义?'
方式1: 通过元字符\\-来在字符列表中列出它。
方式2: 不触发它的特殊含义,也就是它的左右两边不同时出现字符即可。
方式3: 在字符列表中写一个码值范围包含它的字符区间即可。
方式4: 在字符列表中写一个元字符失效区,将它写在元字符失效区内即可。
'脱字符^ 码值94'
^ 特殊含义1: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串必须在文本内容的开
头。
特殊含义2: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串出现在文本任何一行
的开头都可以。
特殊含义3: 它不代表任何字符,它会取反字符列表所能代表的字符。
例如原先自定义元字符代表的字符是字符列表中所列出的字符,但触发脱字符的特殊含
义后,自定义元字符所泛指的字符是字符列表中没列出的字符。
字面含义: 它代表1个脱字符。
字面含义位置: 元字符失效区、非特殊含义位置1、2、3。
特殊含义位置1: 正则表达式的开头。
特殊含义位置2: 正则表达式的开头且引擎被设为多行模式。
特殊含义位置3: 字符列表的开头。
'如何在字符列表写入它的字面含义?'
方式1: 通过元字符\\^来在字符列表中列出它。
方式2: 不触发它的特殊含义,也就是不将它写在字符列表的开头即可。
方式3: 在字符列表中写一个码值范围包含它的字符区间即可。
方式4: 在字符列表中写一个元字符失效区,将它写在元字符失效区内即可。
**********************************************************************************************
'拓展1': 先看一个案例 [^-a] 现在请问它代表的字符是什么?
'答': 它代表的字符是除了-、a两个字符外的所有字符。
'说明': ^写在字符列表开头的优先级大于触发连字符的优先级。
'拓展2': 先看一个案例 [^] 现在请问它代表的字符是什么?
'答': 它会导致'模式语法异常',因为^写在字符列表的开头会导致^字符的特殊含义从而导致字
符列表没有字符。
(5)元字符失效区:
'元字符失效区的基本概念'
(1)元字符失效区是在正则表达式内的特殊书写区域,在该区域内书写任何元字符都是字面含义。
(2)元字符失效区的定义格式: "\\Q内容...\\E"
(3)书写\\Q、\\E、\\Q\\E这三个元字符的相关细节:
1.书写\\Q时,需要注意它是构成元字符失效区的基础元字符,它不应该单独于\\E存在,单独存在会导致
不可预期的一些错误,遵守即可。
2.书写\\E时,需要注意它是构成元字符失效区的基础元字符,它不应该单独于\\Q存在,单独存在会导致
不可预期的一些错误,遵守即可。
3.\\Q、\\E、\\Q\\E都不能嵌套写在元字符失效区内,因为会导致不可预期的一些错误,遵守即可。
4.元字符失效区可以定义在字符列表内。
(6)量词:
量词一览表:
'固定量词'
(1){n}
'贪婪量词'
(2)?
(3)+
(4)*
(5){m,}
(6){,n}
(7){m,n}
'懒惰量词'
(8)??
(9)+?
(10)*?
(11){m,}?
(12){,n}?
(13){m,n}?
'占有量词'
(14)?+
(15)++
(16)*+
(17){m,}+
(18){,n}+
(19){m,n}+
量词详解:
'固定量词'
(1){n} 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为量词固定模式。
固定匹配数: n。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明1': n的值必须在[0,2147483647]之间,不遵守编译不报错,但运行时会抛出'模式语法
异常'。
'异常说明2': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会
抛出'模式语法异常'。
'贪婪量词'
(2)? 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为贪婪模式。
最小匹配数: 0。
最大匹配数: 1。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会抛
出'模式语法异常'。
(3)+ 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为贪婪模式。
最小匹配数: 1。
最大匹配数: 当前至文本末尾所需的匹配字符数。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实意字符。
'异常说明': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会抛
出'模式语法异常'。
(4)* 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为贪婪模式。
最小匹配数: 0。
最大匹配数: 当前至文本末尾所需的匹配字符数。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会抛
出'模式语法异常'。
(5){m,} 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为贪婪模式。
最小匹配数: m。
最大匹配数: 当前至文本末尾所需的匹配字符数。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明1': m的值必须在[0,2147483647]之间,不遵守编译不报错,但运行时会抛出'模式语法
异常'。
'异常说明2': m的值必须小于等于最大匹配数,不遵守编译不报错,但运行时会抛出'模式语法异
常'。
'异常说明3': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会
抛出'模式语法异常'。
(6){,n} 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为贪婪模式。
最小匹配数: 0。
最大匹配数: n若大于当前至文本末尾所需的匹配字符数,则为至文本末尾所需的匹配字符数,反
之为n。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明1': n的值必须在[0,2147483647]之间,不遵守编译不报错,但运行时会抛出'模式语法
异常'。
'异常说明2': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会
抛出'模式语法异常'。
(7){m,n} 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为贪婪模式。
最小匹配数: m。
最大匹配数: n若大于当前至文本末尾所需的匹配字符数,则为至文本末尾所需的匹配字符数,
反之为n。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明1': m的值必须在[0,2147483647]之间,不遵守编译不报错,但运行时会抛出'模式语
法异常'。
'异常说明2': m的值必须小于等于最大匹配数,不遵守编译不报错,但运行时会抛出'模式语法
异常'。
'异常说明3': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时
会抛出'模式语法异常'。
'懒惰量词'
(8)?? 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为懒惰模式。
最小匹配数: 0。
最大匹配数: 1。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会抛
出'模式语法异常'。
(9)+? 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为懒惰模式。
最小匹配数: 1。
最大匹配数: 当前至文本末尾所需的匹配字符数。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实意字符。
'异常说明': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会抛
出'模式语法异常'。
(10)*? 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为懒惰模式。
最小匹配数: 0。
最大匹配数: 当前至文本末尾所需的匹配字符数。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会抛
出'模式语法异常'。
(11){m,}? 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为懒惰模式。
最小匹配数: m。
最大匹配数: 当前至文本末尾所需的匹配字符数。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明1': m的值必须在[0,2147483647]之间,不遵守编译不报错,但运行时会抛出'模式语
法异常'。
'异常说明2': m的值必须小于等于最大匹配数,不遵守编译不报错,但运行时会抛出'模式语法
异常'。
'异常说明3': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时
会抛出'模式语法异常'。
(12){,n}? 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改懒惰模式。
最小匹配数: 0。
最大匹配数: n若大于当前至文本末尾所需的匹配字符数,则为至文本末尾所需的匹配字符数,
反之为n。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明1': n的值必须在[0,2147483647]之间,不遵守编译不报错,但运行时会抛出'模式语
法异常'。
'异常说明2': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时
会抛出'模式语法异常'。
(13){m,n}? 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为懒惰模式。
最小匹配数: m。
最大匹配数: n若大于当前至文本末尾所需的匹配字符数,则为至文本末尾所需的匹配字符
数,反之为n。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明1': m的值必须在[0,2147483647]之间,不遵守编译不报错,但运行时会抛出'模式
语法异常'。
'异常说明2': m的值必须小于等于最大匹配数,不遵守编译不报错,但运行时会抛出'模式语
法异常'。
'异常说明3': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错但运行时
会抛出'模式语法异常'。
'占有量词'
(14)?+ 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为懒惰模式。
最小匹配数: 0。
最大匹配数: 1。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会抛
出'模式语法异常'。
(15)++ 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为懒惰模式。
最小匹配数: 1。
最大匹配数: 当前至文本末尾所需的匹配字符数。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会抛
出'模式语法异常'。
(16)*+ 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为懒惰模式。
最小匹配数: 0。
最大匹配数: 当前至文本末尾所需的匹配字符数。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时会抛
出'模式语法异常'。
(17){m,}+ 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为懒惰模式。
最小匹配数: m。
最大匹配数: 当前至文本末尾所需的匹配字符数。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明1': m的值必须在[0,2147483647]之间,不遵守编译不报错,但运行时会抛出'模式语
法异常'。
'异常说明2': m的值必须小于等于最大匹配数,不遵守编译不报错,但运行时会抛出'模式语法
异常'。
'异常说明3': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时
会抛出'模式语法异常'。
(18){,n}+ 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为懒惰模式。
最小匹配数: 0。
最大匹配数: n若大于当前至文本末尾所需的匹配字符数,则为至文本末尾所需的匹配字符数,
反之为n。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明1': n的值必须在[0,2147483647]之间,不遵守编译不报错,但运行时会抛出'模式语
法异常'。
'异常说明2': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错,但运行时
会抛出'模式语法异常'。
(19){m,n}+ 特殊含义: 它不代表任何字符,它会使前一个字符的匹配策略更改为懒惰模式。
最小匹配数: m。
最大匹配数: n若大于当前至文本末尾所需的匹配字符数,则为至文本末尾所需的匹配字符
数,反之为n。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 当它写在非字面含义位置,且它的前一个位置的字符是实义字符。
'异常说明1': m的值必须在[0,2147483647]之间,不遵守编译不报错,但运行时会抛出'模式
语法异常'。
'异常说明2': m的值必须小于等于最大匹配数,不遵守编译不报错,但运行时会抛出'模式语
法异常'。
'异常说明3': 如果将它写在非字面含义位置且前一个位置没有字符时,编译不报错但运行时
会抛出'模式语法异常'。
'与自定义量词相关的元字符'
(20){ 字面含义: 表示1个左花括号。
字面含义位置: 元字符失效区、字符列表。
禁忌: 该元字符是构成元字符失效区的基础元字符,它不应单独存在,单独存在会导致不可预期的
一些错误,遵守即可。
(21)} 字面含义: 表示1个右花括号。
字面含义位置: 元字符失效区、字符列表。
禁忌: 该元字符是构成元字符失效区的基础元字符,它不应单独存在,单独存在会导致不可预期的
一些错误,遵守即可。
(7)定位符:
定位符一览表:
'定位符'
(1)^
(2)$
(3)\\A
(4)\\z
(5)\\b
(6)\\B
定位符详解:
'定位符的基本概念'
每一个定位符都拥有如下的属性,它大体决定了一个定位符的作用。
筛选基点: 它是引擎筛选目标字符串的依据。
**********************************************************************************************
'演示引擎根据定位符筛选出目标字符串'
文本: "a12aal12"
正则表达式: "^12"
现在引擎要将文本中满足正则表达式每个字符匹配策略的目标字符串替换成"*"。
引擎第1步: 以文本的首字符为匹配点,为表达式字符"1"匹配文本字符[0],匹配失败。
引擎第2步: 引擎根据匹配点是否已到达文本内容末尾来做不同操作,匹配点未到达文本末尾,引擎放弃当
前匹配点,向后移动一位。
引擎第3步: 再以文本的[1]字符为匹配点,为表达式字符"1"匹配文本字符[1],匹配成功。
引擎第4步: 再为表达式字符"2"匹配文本字符[2],然后发现匹配成功。
'引擎第5步': 发现正则表达式已到达末尾,所以文本[1,2]为目标字符串。
引擎第6步: 引擎根据匹配点是否已到达文本内容末尾来做不同操作,匹配点未到达文本末尾,引擎放弃当
前匹配点,向后移动一位。
引擎第7步: 以文本文本的[3]字符为匹配点,为表达式字符"1"匹配文本字符[3]
匹配失败。
引擎第8步: 引擎根据匹配点是否已到达文本内容末尾来做不同操作,匹配点未到达文本末尾,引擎放弃当
前匹配点,向后移动一位。
引擎第9步: 再以文本的[4]字符为匹配点,为表达式字符"1"匹配文本字符[4],匹配失败。
引擎第10步: 引擎根据匹配点是否已到达文本内容末尾来做不同操作,匹配点未到达文本末尾,引擎放弃
当前匹配点,向后移动一位。
引擎第11步: 再以文本的[5]字符为匹配点,为表达式字符"1"匹配文本字符[5],匹配失败。
引擎第12步: 引擎根据匹配点是否已到达文本内容末尾来做不同操作,匹配点未到达文本末尾,引擎放弃
当前匹配点,向后移动一位。
引擎第11步: 再以文本的[6]字符为匹配点,为表达式字符"1"匹配文本字符[6],匹配成功。
引擎第12步: 再为表达式字符"2"匹配文本字符[7],然后发现匹配成功。
'引擎第13步': 发现正则表达式已到达末尾,所以文本[6,7]为目标字符串。
引擎第14步: 发现文本已结束,所以开始筛选目标字符串,如果目标字符串不满足所有的筛选基点,那么
它就不引擎认为是目标字符串。
---------------------------------------------------------------------------------
目标字符串总共有两个: 目标字符串[1,2]、目标字符串[6,7]。
^的筛选基点: 目标字符串必须在文本内容的开头。
引擎第15步: 根据筛选基点来筛选掉目标字符串[6,7],保留目标字符串[1,2]。
引擎第16步: 对目标字符串[1,2]进行替换操作,替换成"*"。
引擎第17步: 结束本次操作。
'综上': 引擎在为表达式字符匹配文本字符时,是不考虑定位符的,只有引擎最后根据筛选基点来对目标
字符串进行筛选时才会使用到定位符。
**********************************************************************************************
'定位符详解'
(1)^ 特殊含义1: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串必须在文本内容的开
头。
特殊含义2: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串出现在文本任何一行
的开头即可。
特殊含义3: 它不代表任何字符,它会取反字符列表所能代表的字符。
字面含义: 它代表1个脱字符。
字面含义位置: 元字符失效区、非特殊含义位置1、2、3。
特殊含义位置1: 正则表达式的开头。
特殊含义位置2: 正则表达式的开头且引擎被设为多行模式。
特殊含义位置3: 字符列表的开头。
(2)$ 特殊含义1: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串必须是文本的结尾子
串。
特殊含义2: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串出现在文本任何一行
的末尾即可。
字面含义: 它代表1个美元字符。
字面含义位置: 元字符失效区、非特殊含义位置1、2。
特殊含义位置1: 正则表达式的结尾。
特殊含义位置2: 正则表达式的结尾且引擎被设为多行模式。
(3)\\A 特殊含义: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串必须在文本内容的开
头。
字面含义: 它代表1个反斜杠和1个A字母的组合。
禁忌位置: 它不能写在字符列表中,如果写了会导致出现预期之外的一些错误,我们遵守即可。
字面含义位置: 元字符失效区、非特殊含义位置。
特殊含义位置: 正则表达式的开头,无论引擎是单行还是多行模式。
(4)\\z 特殊含义: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串必须是文本的结尾子
串。
字面含义: 它代表1个反斜杠和1个z字母的组合。
禁忌位置: 它不能写在字符列表中,如果写了会导致出现预期之外的一些错误,我们遵守即可。
字面含义位置: 元字符失效区、非特殊含义位置。
特殊含义位置: 正则表达式的开头,无论引擎是单行还是多行模式。
(5)\\b 特殊含义: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串在对应正则表达式的
\\b位置+1拥有如下之一的内容。
(空格、制表符、回车符、换行符、文本开头与末尾的"")
字面含义: 它代表1个反斜杠和1个b字母的组合。
禁忌位置: 它不能写在字符列表中,如果写了会导致出现预期之外的一些错误,我们遵守即可。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
(6)\\B 特殊含义: 它不代表任何字符,它会作为定位符,它的筛选基地点是目标字符串在对应正则表达式
的\\B位置+1不能出现如下内容。
(空格、制表符、回车符、换行符、文本开头与末尾的"")
字面含义: 它代表1个反斜杠和1个B字母的组合。
禁忌位置: 它不能写在字符列表中,如果写了会导致出现预期之外的一些错误,我们遵守即可。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
**********************************************************************************************
'拓展'
在单行模式下: 当正则表达式的开头和末尾同时出现^和$时,目标字符串必须得满足它即出现在文本的开
头也要出现在文本的末尾。
在多行模式下: 当正则表达式的开头和末尾同时出现^和$时,目标字符串必须得满足它是文本其中一行内
容的开头与末尾。
(8)自定义定位符:
'自定义定位符的基本概念'
(1)自定义定位符是对定位符的补充,它可以让我们定义自己定位符从而让引擎筛选出指定的目标字符串。
(2)自定义定位符与定位符略有不同,它拥有如下两个属性。
筛选基点: 它是引擎筛选目标字符串的依据。
是否作废: 如果被作废,那么引擎会当它不存在。
**************************************************************************************
'自定义定位符详解'
'代指': 本节用n代指筛选表达式内容的长度。
'技巧': 筛选表达式也是正则表达式,它其中也可以定义各种元字符,元字符中也包括选择匹配符。
(1)(?=筛选表达式..) 特殊含义: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串在对
应正则表达式的
(?=筛选表达式..)位置+n拥有能满足筛选表达式每个字符匹配策略的子
串。
字面含义: 它代表"(?=筛选表达式..)"的字面含义。
作废位置: 它的位置前方没有任何一个字符时,它会被作废,反之!不作废。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 非字面含义位置。
'说明': 若想将其变为非命名捕获分组,只需将?改成\\?的形式。
(2)(?!筛选表达式..) 特殊含义: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串在对
应正则表达式
(?=筛选表达式...)位置+n没有能满足筛选表达式每个字符匹配策略的
子串。
字面含义: 它代表"(?!筛选表达式..)"的字面含义。
作废位置: 它的位置前方没有任何一个字符时,它会被作废,反之!不作废。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 非字面含义位置。
'说明': 若想将其变为非命名捕获分组,只需将?改成\\?的形式。
(3)(?<=筛选表达式..) 特殊含义: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串在对
应正则表达式
(?<=筛选表达式..)位置-n拥有能满足筛选表达式每个字符匹配策略
的子串。
字面含义: 它代表"(?<=筛选表达式..)"的字面含义。
作废位置: 它的位置后方没有任何一个字符时,它会被作废,反之!不作废。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 非字面含义位置。
'说明': 若想将其变为非命名捕获分组,只需将?改成\\?的形式。
(4)(?<!筛选表达式..) 特殊含义: 它不代表任何字符,它会作为定位符,它的筛选基点是目标字符串在对
应正则表达式
(?<!筛选表达式..)位置-n没有能满足筛选表达式每个字符匹配策略
的子串。
字面含义: 它代表"(?<!筛选表达式..)"的字面含义。
作废位置: 它的位置后方没有任何一个字符时,它会被作废,反之!不作废。
字面含义位置: 元字符失效区、字符列表。
特殊含义位置: 非字面含义位置。
'说明': 若想将其变为非命名捕获分组,只需将?改成\\?的形式。
(9)捕获分组与反向引用:
'捕获分组'
(1)捕获分组分为两种:
非命名捕获分组: (子表达式)
命名捕获分组: (?<name>子表达式)
(2)非命名捕获分组的基本概念:
1.非命名捕获分组拥有组号。
2.我们可以通过组号在正则表达式中调用对应组匹配到的子串。
3.书写非命名捕获分组的细节如下:
特殊含义: 它代表1个组,该组所匹配到的文本字串会保存在一个变量中以供后续调用。
字面含义: 它代表"(子表达式)"的字面含义。
字面含义位置: 字符列表、元字符失效区。
特殊含义位置: 非字面含义位置。
(3)命名捕获分组的基本概念:
1.命名捕获分组不仅拥有组号还拥有组名。
2.组名也是标识符,我们应该遵守标识符的书写规则与规范。
3.我们可以通过组号与组名在正则表达式中调用对应组匹配到的子串。
4.书写命名捕获分组的细节如下:
特殊含义: 它代表1个组,该组所匹配到的文本子串会保存在一个变量中以供后续调用。
字面含义: 它代表"(?<name>pattern)"的字面含义。
字面含义位置: 字符列表、元字符失效区。
特殊含义位置: 非字面含义位置。
'说明': 若想将其变为非命名捕获分组,只需将?改成\\?的形式。
(4)组号给予规则: 引擎在正则表达式中从数字1开始按序给予每个捕获组对应的组号。
(5)反向引用符的细节:
\\组号 特殊含义: 它代表引用组号对应组所匹配到的子串。
字面含义: 1个反斜杠+一个数字。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
'异常说明1': 它不能写在字符列表中,如果写在字符列表中,编译不报错,但运行时会导
致'模式语法异常'。
'异常说明2': 它若引用不到组号对应的组,也就是没有这个组,编译不报错,但运行时会导
致'模式语法异常'。
\\k<组名> 特殊含义: 它代表引用组名对应组所匹配到的子串。
字面含义: 1个反斜杠+"<组名>"的字面含义。
字面含义位置: 元字符失效区。
特殊含义位置: 非字面含义位置。
'异常说明1': 它不能写在字符列表中,如果写在字符列表中,编译不报错,但运行时会导
致'模式语法异常'。
'异常说明2': 它若引用不到组名对应的组,也就是没有这个组,编译不报错,但运行时会导
致'模式语法异常'。
**************************************************************************************
'案例'
正则表达式: "a(\\d|(bc))(?<n1>\\1)\\2\\3"
问题1: 请说出上面正则表达式有几个组?
问题2: 每个组的组号和组名分别是什么?
问题3: 请写出1个能与该正则表达式所匹配的目标字符串。
'答1': 3个组。
'答2': (\\d|(bc)) 对应组号是 1。
对应的组名是 无。
--------------------------
(bc) 对应的组号是 2。
对应的组名是 无。
--------------------------
(?<n1>\\1) 对应组号是 3。
对应组名是 n1。
'答3': 目标字符串"abcbcbcbc"
'拓展'
(1)从上面的案例可以看出,选择匹配符不会影响组号给予规则。
(2)选择匹配符不会影响捕获组的逻辑,\\3不存在引用,那么走的\\d这条路的已匹配的文本子串就不符合
逻辑。
(10)非捕获分组:
'非捕获分组'
(?:子表达式) 特殊含义: 它代表1个非捕获分组,它不会被给予组号和组名,所以它匹配到的内容后续是无
法被反向引用符调用的。
字面含义: "(?:子表达式)"的字面含义。
字面含义位置: 字符列表、元字符失效区。
特殊含义位置: 非字面含义位置。
'说明': 若想将其变为非命名捕获分组,只需将?改成\\?的形式。
'作用1': 非捕获分组的作用仅是提高正则表达式的可读性,让目标字符串的结构呈现模块
化。
'作用2': 在特殊的业务场景下,它还可以提高正则表达式的复用性。
'举例': "abc|acd" 可以变为 "ab(?:c|d)"
'拓展': 其实自定义定位符也是非捕获分组,但是它们的作用不同于上面那种,所以我将它们单开了一章。