正则表达式笔记
文章目录
正则指令集
ps: 引号为标注
一 、 特殊指令
匹配内容
指令 | 规则释义 |
---|---|
. | 匹配除了换行符以外的任意字符 |
* | 代表匹配数量 指定*前边的内容可以连续重复使用任意次以使整个表达式得到匹配 |
{N} | 代表前面连续匹配多少次 |
{5,12} | 代表指定前面连续匹配次数 重复的次数不能少于5次,不能多于12次 |
\s | 任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等 |
\w | 匹配字母或数字或下划线或汉字等 |
+ | 匹配重复1次或更多次 类似 * 指令 区别 *指令可以匹配 0 次 + 指令 1次及以上 |
匹配位置
指令 | 规则释义 |
---|---|
\b | 代表单词的开头或结尾也就是单词的分界处 只匹配一个位置不匹配内容 |
^ | 匹配字符串的开始 |
$ | 匹配字符串结尾 如果 ^ $ 一起使用代表是精准匹配 |
字符转义符
指令 | 规则释义 |
---|---|
\ | 来转义 可以将指令取消特殊意义 例如:匹配 . 或 * 你应该使用.和*。当然,要查找\本身,你也得用\. |
重复类限定符
指令 | 规则释义 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
字符类
ps : 匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u)
例如:
[0-9] : 匹配字符范围
[a-z0-9A-Z_] : 匹配 字母A到Z 和数字 0至9
二、 逻辑指令
分枝条件
指令 | 规则释义 |
---|---|
exp | exp | 使用多个逻辑匹配规则进行选择 满足其中任意一种规则都应该当成匹配 |
三、 子表达式指令 (分组)
ps : 可以将表达式拆分成多个子表达式 并且可以重复匹配使用以及一些高级操作
"()" : 小括号的方式来表示组成子表达式
例如:
1. "(\d{1,3}\.){3}\d{1,3}" : 匹配IP格式地址 \d{1,3} 匹配三位数字 \. 转义匹配 . "(\d{1,3}\.)" 整体就是个分组 {3} 重复匹配3次 最后再加上一个1到3位的数字 (\d{1,3})
2. "((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)" : 匹配标准IP地址 分组基础上 加入字符类的限定和分支逻辑判断即可
四、 反义指令
ps: 查找不属于某个能简单定义的字符类的字符
反义指令
"\W" : 匹配任意不是字母,数字,下划线,汉字的字符
"\S" : 匹配任意不是空白符的字符
"\D" : 匹配任意非数字的字符
"\B" : 匹配不是单词开头或结束的位置
"[^x]" : 匹配除了x以外的任意字符
"[^aeiou]" : 匹配除了aeiou这几个字母以外的任意字符
五、 后向引用
ps: 用于重复搜索前面某个分组匹配的文本; 使用场景: 用于和分组组合使用
使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其他程序中作进一步处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。
例如:
"\b(\w+)\b\s+\1\b" : 可以用来匹配重复的单词 像go go 就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。 此处为什么使用 "\1" 呢 因为在表达式中使用\n 是代表反向引用使用的 "代表获取第几组捕获内容"
"\b(?<Word>\w+)\b\s+\k<Word>\b" : 跟上个例如一样, 此处自定义了组名 不以数字编号为组名了。"(?<name>exp)" 自定义分组名称 "\k<"name">" 调用分组了
六、 零度断言
定义:
如同 ^ 代表开头,$ 代表结尾,\b
代表单词边界一样,先行断言和后行断言也有类似的作用,它们只匹配某些位置,在匹配过程中,不占用字符,所以被称为"零宽"。所谓位置,是指字符串中(每行)第一个字符的左边、最后一个字符的右边以及相邻字符的中间(假设文字方向是头左尾右)。
1、关于先行(lookahead)和后行(lookbehind):
正则表达式引擎在执行字符串和表达式匹配时,会从头到尾(从前到后)连续扫描字符串中的字符,设想有一个扫描指针指向字符边界处并随匹配过程移动。
先行断言: 是当扫描指针位于某处时,引擎会尝试匹配指针还未扫过的字符,先于指针到达该字符,故称为先行。
后行断言: 引擎会尝试匹配指针已扫过的字符,后于指针到达该字符,故称为后行。
2、关于正向(positive)和负向(negative):正向就表示匹配括号中的表达式,负向表示不匹配。
对这 4 个断言形式的记忆:
1、先行和后行:后行断言 (?<=pattern)、(?<!pattern) 中,有个小于号,同时也是箭头,对于自左至右的文本方向,这个箭头是指向后的,这也比较符合我们的习惯。把小于号去掉,就是先行断言。
2、正向和负向:不等于 (!=)、逻辑非 (!) 都是用 !号来表示,所以有 ! 号的形式表示不匹配、负向;将 ! 号换成 = 号,就表示匹配、正向。
七、贪婪与懒惰
定义:
—贪婪
当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。
以这个表达式为例:a.b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
例如:
"." 匹配最长 但遇到后面有其他限定符则不会贪婪匹配 比如: .*?
—懒惰
-
有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。
-
前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复
例如:
"*?" : 重复任意次,但尽可能少重复
"+?" : 重复1次或更多次,但尽可能少重复
"??" : 重复0次或1次,但尽可能少重复
"{n,m}?": 重复n到m次,但尽可能少重复
"{n,}?" : 重复n次以上,但尽可能少重复