创建正则表达式
有两种创建正则表达式的方式:
- 1.创建斜杠之间创建正则匹配模式
const re = /abc/
- 2.创建正则表达式对象
const re = new RegExp("abc")
验证字符串是否匹配
该函数用于验证一个字符串是否能与该模式进行匹配,返回 bool 类型。
const re = new RegExp('abc')
console.log(re.test('abc')) // true
console.log(re.test('abb')) // false
console.log(re.test('acc')) // false
匹配模式方法也类似,直接F12调出控制台就能测试这段代码:
正则匹配规则(重点🫵🤓)
几个例子
表达式 | 描述 |
---|---|
[abc] | 匹配 [abc] 之中的任意一个字符 |
[a-c] | 同上 |
[^abc] | 匹配 [abc] 以外的任意一个字符 |
[A-Z] | 匹配任意大写字母 |
[a-z] | 匹配任意小写字母 |
[0-9] | 匹配任意数字 |
元字符
表达式 | 描述 |
---|---|
. | 匹配除换行符之外的任何单个字符 |
\w | 匹配数字、字母、下划线 |
\W | 匹配非数字、字母、下划线 |
\d | 匹配数字 |
\D | 匹配非数字 |
\s | 匹配空白字符(空格、换行) |
\S | 匹配非空白字符 |
\n | 匹配换行符 |
开头与结尾
表达式 | 描述 |
---|---|
^abc | 匹配以 abc 开头的字符串 |
abc$ | 匹配以 abc 结尾的字符串 |
^abc$ | 完全匹配字符串 abc |
量词
量词 | 描述 |
---|---|
* | 匹配前面的子表达式零次或多次 |
+ | 匹配前面的子表达式一次或多次 |
? | 匹配前面的子表达式零次或一次 |
{n} | 匹配确定的 n 次 |
{n,} | 至少匹配 n 次 |
{n,m} | 最少匹配 n 次且最多匹配 m 次 |
特殊功能
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配 |
g | 执行全局匹配 |
m | 执行多行匹配 |
实例
console.log(/^Java/.test('JavaScript')) // true
console.log(/^java/.test('JavaScript')) // false
console.log(/^java/i.test('JavaScript')) // true
console.log(/Java$/.test('JavaScript')) // false
console.log(/^Java$/.test('JavaScript')) // false
console.log(/^[abc]TML$/.test('HTML')) // false
console.log(/^[^abc]TML$/.test('HTML')) // true
console.log(/^[A-Z]TML$/.test('HTML')) // true
console.log(/^\w+$/.test('HTML')) // true
console.log(/^\W+$/.test('HTML')) // false
console.log(/^\d?$/.test('0123')) // false
console.log(/^\d{2,4}$/.test('0123')) // true
正则方法(重点+1)
正则表达式有如下方法可供调用:
re.test()
方法re.exec()
方法str.match()
、str.matchAll()
方法str.replace()
、str.replaceAll()
方法str.search()
方法str.split()
方法
不好意思,全都要掌握。
re.exec()方法
re.test()方法过于简单,前面也提到了,省略。从exec()开始说起。
let reg = new RegExp(/(HTML)\d+(?<name>\w+)/);
console.log(reg.exec('[HTML123CSS]'))
console.log(/(HTML)\d+(?<name>\w+)/.exec('[HTML123CSS]'))
这里两种正则的方法都演示一遍,后面就不用对象的写法了,可以看到结果一样。
这里比较重要的一个概念是捕获组,还是看上面这个代码,第一个括号中包裹的部分就是一个捕获组,意思就是告诉Js:“给我捕获这个括号内匹配到的内容!”。你可以在该列表的第二个变量开始看到所有你捕获到的内容(值得一提的是,列表第一个元素是你给定待匹配的字符串)。
那么第二个括号中包裹的内容呢?第二个括号中包裹的也是捕获组,但是它还有一个额外的写法:”<?name>\w+”。这里的<?name>
是一种特殊的语法,意思是将这个括号中捕获到的内容不仅塞到列表里,还要额外给一个叫做name的键名,你可以在最后一个元素groups中看到这个被捕获的变量(groups.name="CSS"
),它的键名确实是name
,当然,你可以写成别的名称,例如:<?小明>
、<?Jack>
等。
了解捕获组的用法后,恭喜你解决了最大的难点,其余方法基本很简单了。
str.match()方法&str.matchAll()方法
console.log(/(HTML)\d+(?<name>\w+)/.exec('[HTML123CSS]'))
console.log('[HTML123CSS]'.match(/(HTML)\d+(?<name>\w+)/))
输出结果完全一样,match和exec方法使用上基本一样,区别在于,如果在最后一个/后面加上全局标志,可以不使用捕获组直接返回所有的匹配结果。
console.log(/(HTML)\d+(?<name>\w+)/g.exec('[HTML123CSS]'))
console.log('[HTML123CSS]'.match(/(HTML)\d+(?<name>\w+)/g))
加上全局标志我们再来看下输出:
可以看到match方法可以使用全局标志g
来进行全局匹配,这样就没有捕获组了,匹配到的元素都在数组里。
为了解决match使用g全局匹配时不考虑捕获组这个问题,诞生了matchAll()方法:
console.log([...'[HTML123CSS]'.matchAll(/(?<name>[A-Z]+)/g)])
可以看到,每一个捕获到的值都有对应的捕获组。
str.replace()方法&str.replaceAll()方法
console.log('[HTML123CSS]'.replace(/[A-Z]+/, 'ABC'))
console.log('[HTML123CSS]'.replace(/[A-Z]+/g, 'ABC'))
console.log('[HTML123CSS]'.replaceAll(/[A-Z]+/g, 'ABC'))
输出结果:
可以看出,该操作只会替换匹配到的第一个,如果需要替换所有匹配到的模式,添加全局标志g
。
如果利用正则表达式的分组语法,可以实现替换匹配字符串的部分的功能,例如:我需要找到所有电话号码,并将电话号码中间的5位替换成*
,就可以使用下面的正则进行替换:
str = str.replace(/(1[35789]+\d{1})\d{5}(\d{3})/g, `$1${symbols}$2`)
我们在这里需要替换的结果使用了模版字符串,$1
、$2
用来占位第一组和第二组不做替换,${symbols}
用来将中间的元素替换为模版字符串外面写好的变量,let symbols = '*'
。
str.search()方法
console.log('[HTML123CSS]'.search(/[A-Z]+/))
该方法会返回匹配模式被搜索到的第一个位置。
str.split()方法
console.log('[HTML123CSS]'.split(/[A-Z]+/))
console.log('[HTML123CSS]'.split(/([A-Z]+)/))
console.log('[HTML123CSS]'.split(/([A-Z]+)/, 2))
该方法会将字符串按照匹配的模式进行分割,返回被分割后字符串数组。默认情况下,被匹配的模式将不出现在结果数组,如果使用()
的捕获写法将会出现在结果数组。
不错
❀٩(ˊᗜˋ*)و