
现在开始写 高级篇,话不多说,开始表演

1
贪婪匹配、惰性匹配
正则默认是贪婪匹配的,为什么一开始设计默认是贪婪呢?我估计,是设计者想设计得人性化一些

1
贪婪匹配
当使用 量词 的时候 ,默认都是贪婪匹配,匹配得越长越好
一个短的匹配项 是合规的,一个长的匹配项也是合规的,那么贪婪匹配会选择长的
量词都有哪些?
参考我的上一篇基础篇
【怕啥弄啥系列】总要爱上它《正则》 - 基础
2
惰性匹配
一个短的匹配项 是合规的,一个长的匹配项也是合规的,那么惰性匹配会选择短的
当我们在量词的后面加上一个 ? ,那么就是 惰性匹配
3
统一举例对比
1、使用符号量词
+ | 1 | 更多 |
|---|---|
* | 0 | 更多 |
? | 0 | 1 |
贪婪匹配
"<>>".match(/<(.*)>/g)
"<>>".match(/<(.?)>/g)
"<>>".match(/<(.+)>/g)清一色越多越好,没有哄你的

惰性匹配,在 量词 后面加上 ?
"<>>".match(/<(.*?)>/g)
"<>>".match(/<(.??)>/g)
"<>>".match(/<(.+?)>/g)看到了吧,就变成匹配更少的了

2、数字量词
虽然给定了区间 ,默认也是尽可能以最大的区间值进行匹配
"<>b>".match(/<(.{1,})>/g)
"<>b>".match(/<(.{1,3})>/g)<>b> 和 <> 都是合规的,但是 贪婪匹配 只会匹配更长的

试下惰性匹配,加上 ?
"<>b>".match(/<(.{1,}?)>/g)
"<>b>".match(/<(.{1,3}?)>/g)<>b> 和 <> 都是合规的,但是惰性匹配只会匹配更短的

2
分组、捕获
1
分组
在 正则表达式中加入 小括号 表示分组
像是这样
/(d)/.exec("adg")2
捕获
正则 的 括号部分 的匹配项,独立捕获出来
捕获这个动作,一般配合 正则 的 exec 方法
举栗子
比如下面,想把1 和 3 之间的数字捕获出来,中间就要加上括号

你看到了,返回的数组中,有几项内容
第一项,匹配项,是123,对应 1(\d)3
第二项,捕获分组,是 2,对应 (\d)
第三项,匹配的起始位置,123在字符串中的起始位置是1
第四项,匹配的源字符串,a123
3
捕获 型分组
加了括号,就叫捕获型分组。而且匹配时会把每个分组给保存起来
TIP:可以同时捕获很多个,只要你加了 多个括号

4
非捕获型分组
加了括号,但是不捕获,就叫 非捕获分组
比如,我 加括号是为了使用 分隔符表示或者 的意思
/\w(2|3)/.exec("ab2 ab3")这里为了表示 匹配 2 或者 3,但是你却把他捕获出来了,我不想要啊

怎么办!
这时候就用到 非捕获型分组
敲黑板,重点来了,看这里 ?:
没错,你看到的就是 非捕获分组的重点,记下来,要考!
怎么用!
把 ?: 放在正则 括号内的开头 就可以了
举栗子

哈哈,you 就不会被捕获出来啦
想使用括号,但是不想捕获,就用 非捕获型分组
3
引用、反向引用
这两个东西,是属于 捕获型分组 的内容,只有在捕获型分组中才存在 引用和 反向引用
1
引用
引用的意思,按我的理解就是引用捕获到的分组
1、Regexp对象 获取 引用
Regexp对象 会保存 最近的捕获的分组
所以在 Regexp 上可以获取到 最近的捕获的分组
举栗子

每次捕获一次,RegExp 就会 替换保存 最新的捕获分组
RegExp 的 $1 - $9 都可以保存分组,也就是可以保存 9 个分组
打印一下 RegExp 这个函数对象

Tip
使用 console.dir 打印 RegExp,因为它是个函数对象,直接 log 打印,会看不到它的属性
2、 replace 使用 引用
同样是使用 $1 -$9 的形式去引用捕获分组,然后把它放在第二个参数中

replace 使用 引用,我一般用来匹配那些 不确定是否存在 的 的向
举栗子
比如 这样的字符串
<p>111</p><a>222</a><b>333</b>
我要把所有的标签都改成 p 标签,我需要匹配标签,首标签不存在 /, 而尾标签存在 /,我替换时不确定 / 是否存在,所以我需要去把 / 放入分组进行捕获
如果匹配到,那么是尾标签,替换时就要 / ,如果没有匹配到,是首标签,替换时不用 /
"<p>111</p><a>222</a><b>333</b>".replace(/<(\/?)\w>/g,"<$1p>")$1 标签 表示 是否存在 / 这个匹配分组
a、如果存在 / ,<$1p> 变成 </p>
b、如果不存在 / ,<$1p> 变成 <p>
这样就能同时匹配 首尾两种标签了

2
反向引用
在 正则表达式中 引用分组,减少写重复的代码,相当于使用一个变量
用法注意事项
1、必须要使用分组
2、转义+数字 表示引用第几个分组
1、必须要使用分组
就是正则中必须有括号喽
/(\w)/2、转义+数字 表示引用 正则 中的第几个分组
/(\w)(\d)\1\2/那么 (\w) 是第一个分组,(\d) 是第二个分组
\1 表示 引用第一个分组,\2 表示引用第二个分组,而 数字需要转义,所以加上 \
上面的正则,意思是先匹配到 AB,然后使用 AB 这两个分组,去匹配 ABAB

通常我会使用它,进行匹配 头尾相同 的内容
举栗子
比如下面的字符串
<p>111</p><a>222</a><b>333</b>
如果我想匹配 出 <p>111</p> 、<a>222</a> 这样,但是我怎么控制首尾标签的名字一样呢?
反向引用,在这里就起作用了
"<p>33</p> <a>11</a> <div>11</div>".match(/<(\w)>.+<\/\1>/g)这样,就能保证首尾标签一样了

最好配合 惰性匹配 使用,否则 匹配的 p 标签 就会包含很多个

这样,加上 ?进行惰性匹配,就是正确的了

4
正向前瞻,反向前瞻
前瞻的用法,类似于排除过滤的功能,只要 后面 有什么 或者 没有什么 的内容
1
正向前瞻
简单说
就是匹配 后面跟着某些内容 的 字符串
我要匹配一个东西,他后面必须跟着某个东西!
常用于排除过滤功能
重点符号 ?=
TIP
1、把 这个符号放在 需要跟着的内容 的前面
2、需要使用小括号把最外层包起来
举栗子
这样说,现在有一串字符串
"I coding, I eat, I smile" , 我只想拿到I I coding 这一段,就是我要 后面有 coding 的 I
那么使用正向前瞻做法就是
'I coding,I eat,I smile'.match(/hoho(?=\scoding)/g)
2
反向前瞻
简单说
反向前瞻,匹配 后面不跟着某些内容 的 字符串
我要匹配一个东西,他后面不能跟着某个东西!
重点符号 ?!
TIP
1、把 这个符号放在 不需要跟着的内容 的前面
2、需要使用小括号把最外层包起来
举栗子
这样说,现在有一串字符串
"I coding, I eat, I smile" , 我不想拿到I I coding 这一段,就是我要 后面没有 coding 的 I
额.....又是一样的例子
使用反向前瞻做法就是
'I coding,I eat,I smile'.match(/hoho(?=\scoding)/g)