本文正在参加「金石计划 . 瓜分6万现金大奖」
正则表达式 方法
前言
推荐先阅读 手摸手快速入门 正则表达式 (基础)🛫 ,再阅读本文。
本文主要讲解是关于 js 的 string 类型中, 有哪些与 正则 有关的方法
与 正则有关的 string 方法
正则 Regexp 的方法,除了它自己本身,还有很多 字符串 String中的方法,也是与正则有关系。
-
不是正则
RegExp它拥有的方法 -
而是 字符串
String拥有的方法
下面我们看下 String 中,哪些方法与 正则 有关联
| 方法名 | 含义 |
|---|---|
| match | 找到一个或多个 正则表达式 的匹配 |
| matchAll | 返回包含所有匹配 正则表达式 的结果的 迭代器 |
| replace 和 replaceAll | 替换 并返回一个新值,不影响原来的值 |
| search | 返回与之匹配的 字符串或字符 的下标,没找到则为 -1 |
| split | 字符串分割成数组,数组中不包含匹配到的值 |
总共有6个与之相关的方法,下面我会详细讲解一下这些方法的使用
1 match 方法
关于 match 方法, 这里分了两种情况,一种是 reg 为 正则表达式;另一个 reg 为 字符串
我们先从第一种情况中,知道下这个方法 如何使用:
1.1 reg 的值为 正则表达式
const reg = /\d+/
const str = 'wzms123wzms9,456wzms,789'
const result = str.match(reg)
可以看到结果与 正则的 Regexp.exec() 方法,得到的结果一样。
说明也是返回 匹配到第一个符合条件的值,并且也是数组。
所以有时候,我们经常使用 String 的 match 方法 来代替 Regexp 的 exec 方法
-
疑问
这个时候,你可能会产生疑问?既然有一样的了,那这方法还有什么别的意思吗?
其实还有一种情况,上面都是 只匹配到 第一个符合条件的 ,就进行返回
但是我们有时候,想要的是,匹配所有符合条件的值,进行返回。例如,我想要上面
str这个里面,所有的数字。 -
解答
那这个时候,就需要我们的 修饰符 了,我们通过给
reg添加 修饰符 g,来进行处理const reg = /\d+/g const str = 'wzms123wzms9,456wzms,789' const result = str.match(reg)可以看到返回结果是一个数组,里面的值是
str中所有的数字 所组成的。
1.2 reg 为 字符串
当 reg 的值为 字符串 时,我们看下它做了什么事情
const reg = 'wz'
const str = 'wzms123wzms9,456wzms,789'
const result = str.match(reg)
可以看到也是能匹配的,会匹配第一个符合条件的,并返回数组
但是这么做的意义好像不大,这样做,我们都知道查什么了,难道为了找下标?那还不如用 String 的 indexOf 方法
-
这里我就再举一个例子
如果我传入
reg的值为'\\d+',结果会是什么?const reg = '\\d+' const str = 'wzms123wzms9,456wzms,789' const result = str.match(reg)可以看到结果与我们传入 正则表达式 的效果一样
-
解答
其实,如果我们传入的
reg的值为 字符串时,它会将我们的reg进行一次new RegExp(reg)的操作也就是所谓的 隐式的调用,将其转为 正则表达式 所以才会得到
总结
总结一下这个 match 方法
-
在大多数情况下,我们只需要传入 正则表达式 即可。
-
对于匹配失败,那么返回的值,则为
null -
对于匹配成功后,返回的结果值,都是 数组。
-
如果 有 修饰符 的作用,返回的值则是匹配的内容
-
如果 没有 修饰符 ,作用和
RegExp的exec方法一样
-
-
如果参数为 字符串,则会 隐式的调用
new RegExp(reg)的操作,将 字符串 转成 正则表达式,然后进行匹配。
2 matchAll
首先来说一下这个方法的主要作用
通过上面的 match 方法,可以看到一个缺陷,我们虽然能够通过 修饰符 g 来进行全局的匹配,来获得所有匹配的值。
但是也失去了很多有效信息,例如 下标 index 值,我们看下对比图
-
会发现左图的信息明显很少,仅仅匹配到所有的值,无法知道每个值的具体下标。
-
而右侧的图,虽然只能匹配到一个值,但是信息很多。
所以这个 matchAll 方法的作用,就是将两者结合,匹配到所有的值,并且有详细的信息
来看一下如何使用吧
const reg = /\d+/g
const str = 'wzms123wzms9,456wzms,789'
const result = [...str.matchAll(reg)]
可以看到返回的值很详细。
我们也总结分析下,有哪些限制条件
-
首先必须拥有 修饰符 g,否则会报错
-
由于得到的结果是一个 迭代器
我们可以通过
for ... of、[...]、Array.from()来获得里面的值for (const match of str.matchAll(reg)) { console.log(match) } const b = [...str.matchAll(reg)] const b = Array.from(str.matchAll(reg));
3 replace 和 replaceAll
对于 replace 和 replaceAll 来说,它们不会改变原来的值,只会返回一个新的替换后的值
它们都拥有两个参数,而且这两个参数挺有意思的,
由于这两个 API 很类似,这里就拿 replace 举例
当然会在有区别的时候,告诉小伙伴们的。下面一起来看一下
str.replace(regexp|substr, newSubStr|function)
-
第一个参数:可以为 正则表达式 ,也可以为 字符串
-
第二个参数:可以为 字符串,也可以为 函数
它们 两两组合,这个 replace 就拥有了四种写法
这里就来举个例子,然后通过这四种方法,分别实现一下:
- 将一个 字符串 中,所有的数字,替换成
kai😄xin
3.1 (regexp, newSubStr)
(regexp, newSubStr) 第一个参数为 正则表达式,第二个参数为 字符串
const reg = /\d+/g
const str = 'wzms123wzms9,456wzms,789'
const newStr = str.replace(reg,'kai😄xin')
可以看到成功的替换
3.1 (regexp, function)
(regexp, newSubStr) 第一个参数为 正则表达式,第二个参数为 函数
const reg = /\d+/g
const str = 'wzms123wzms9,456wzms,789'
const newStr = str.replace(reg, () => {
return 'kai😄xin'
})
这里成功的替换了,但是这里有个疑问点:
-
既然是函数,这个函数有传入的参数值吗?
答案是 有的
我们添加一行代码,即可知道这个传入的参数值是什么!
const newStr = str.replace(reg, args => { console.log(args, 'args') return 'kai😄xin' })可以看到每次传入的参数,是我们成功匹配到的值。这就给我们了很多能操作的空间。
3.3 (substr, newSubStr)
(substr, newSubStr) 第一个参数为 字符串,第二个参数也是 字符串
对于这种情况,其实不太好实现上面我说的例子,也不太好理解。
所以我们换个角度,换个例子,来理解下这种情况。
-
将 字符串 中的
wzms全部替换成kai😄xinconst str = 'wzms123wzms9,456wzms,789' const newStr = str.replace('wzms', 'kai😄xin')可以看到只替换了一个,并没有全部的替换。这很明显是不符合我们的要求
这个时候,就需要
replaceAll方法,它能够将所有符合条件的全部替换这也就是这两个
API区别之一const str = 'wzms123wzms9,456wzms,789' const newStr = str.replaceAll('wzms', 'kai😄xin')
3.4 (substr, function)
(substr, function) 第一个参数为 字符串,第二个参数为 函数
对于这个情况,我们也用下面的例子来讲解
-
将 字符串 中的
wzms全部替换成kai😄xinconst str = 'wzms123wzms9,456wzms,789' const newStr = str.replace('wzms', () => { return 'kai😄xin' })可以看到也是只替换了一个,所以我们还是得需要
replaceAll这个方法来全部进行替换const str = 'wzms123wzms9,456wzms,789' const newStr = str.replaceAll('wzms', () => { return 'kai😄xin' })
总结
replace 和 replaceAll 有着很相同的特性
它们的区别就是在匹配时,如果第一个参数是 字符串,则会产生不同的结果
一般情况下,我们在对齐使用 正则表达式 的情况下,一般使用 replace 方法就可以了。
当然在这里,我们已经学会了最基础的使用。
之后在进阶的部分,还会再次对 replace 进行扩充的!
4 search
先说一下,这个方法就是查找的意思,这个方法 与 String 的 indexOf 方法类似,都是寻找匹配的目标值,然后返回 第一个符合条件的值 的 下标
但是不同的是,search 传入的参数
-
既可以传入 字符串,也可以传入 正则表达式
-
值得注意的是,当传入
字符串,则会被new Regexp做一次 隐式的调用,将其转为 正则表达式
我们来使用一下
const reg = /\d+/g
const str = 'wzms123wzms9,456wzms,789'
const result = str.search(reg) // 4
如果查找不到的话,返回值则为 -1
5 split
split 方法,主要是分割的作用,平时在项目中,其实使用的很多,也是最近才发现可以进行 正则 方法的操作。看来得补补基础了😂
它主要有两个参数
-
第一个参数的 可以是 字符串,也可以是 正则表达式
- 如果我们第一个参数不传递,则默认给空字符串
'',进行分割
- 如果我们第一个参数不传递,则默认给空字符串
-
第二个参数 则为长度
length,就是得到数组的长度。-
假设传递 2,则数组内,就只有两个值
-
5.1 正则表达式
const reg = /\d+/
const str = 'wzms123wzms9,456wzms,789'
const result = str.split(reg)
可以看到 是以 我们的 正则表达式 匹配到的字符进行分割,然后得到分割后的数组
来看下我们传递第二个参数 length
const reg = /\d+/
const str = 'wzms123wzms9,456wzms,789'
const result = str.split(reg, 2)
可以看到只有两个值
5.2 字符串
const str = 'wzms123wzms9,456wzms,789'
const str2 = ','
const result = str.split(str2)
可以看到,我们通过 ',' 字符,进行分割 字符串,是成功的
问题也来了,它会像 match 方法一样吗?如果是 字符串,则会 隐式的调用 吗?
下面我们尝试下
const str = 'wzms123wzms9,456wzms,789'
const str2 = '\\d+'
const result = str.split(str2, 2)
可以看到,并没有进行任何的分割,看来不会进行 隐式的调用 new RegExp(reg) 的操作。