分组()
正则是使用()进行的分组,这里也可以说()的作用是什么
1、改变优先级
比如匹配一个数字16或者58
x|y表示x或者y中的一个,但是有时候他的匹配就很模糊,加上小括号后改变优先级让他先处理x|y
2、分组引用
有的时候在匹配字符串的时候会出现重复的内容,这个时候可以使用分组匹配对应分组的内容
(\w+)\1: 首先(\w+)就是数字字母下划线出现一到多次,小括号就是分组,然后后面出现了一个\1这个是指出现和第一个分组一样的字符串比如(\w+)是reg那么\1就必须是reg,那么(\w+)\1就是regreg
(\d+)\2: (\d+)就是数字出现一到多次,\2就是第二个分组,从左到右第二个小括号就是里面的内容是\d+所以这里如果\d+是123那么\2也是123合起来就是123123
\1:就是第一个分组方才的第一个分组是reg所以这里就还要出现一次reg
总结:分组引用就是(规则)\数字,规则就是需要重复的内容,\数字就是你要重复哪一个分组的内容
3、分组捕获
正则在捕获的时候默认是把大正则捕获的内容返回,但是如果你想要捕获一些特别的内容就需要分组这样就可以返回分组捕获的内容
比如捕获年月日,分别在想要获取的结果上添加分组则捕获的结果会返回对应的值
exec捕获的结果:
第一项:默认捕获的结果
其余项:小分组捕获的结果
const reg = /^\d{4}年\d{1,2}月\d{1,2}日$/
console.log(reg.exec('2022年1月28日'))
=> ['2022年1月28日', index: 0, input: '2022年1月28日', groups: undefined]
const reg = /^(\d{4})年(\d{1,2})月(\d{1,2})日$/
console.log(reg.exec('2022年1月28日'))
=> ['2022年1月28日', '2022', '1', '28', index: 0, input: '2022年1月28日', groups: undefined]
捕获的特性
捕获有两个特性懒惰性和贪婪行
1、懒惰性:每次执行exec捕获了之后再次执行又是从头开始匹配,这样只能捕获到第一个匹配的内容,lastIndex是正则每次捕获在字符串中开始查找的位置,可以看到每次都是0,说明是从头开始匹配的
const reg = /\d+/
const str = 'q12q34r'
console.log(reg.exec(str)) => ['12', index: 1, input: 'q12q34r', groups: undefined]
console.log(reg.lastIndex) => 0
console.log(reg.exec(str)) => ['12', index: 1, input: 'q12q34r', groups: undefined]
console.log(reg.lastIndex) => 0
console.log(reg.exec(str)) => ['12', index: 1, input: 'q12q34r', groups: undefined]
console.log(reg.lastIndex) => 0
解决懒惰性就是添加一个全局修饰符g
原理:加了全局修饰符之后lastIndex会在每次匹配捕获后更新为最新的值,下一次捕获就从最新的位置开始查找,这样就可以把所需要的内容都捕获到了。
const reg = /\d+/g
const str = 'q12q34r'
console.log(reg.exec(str)) => ['12', index: 1, input: 'q12q34r', groups: undefined]
console.log(reg.lastIndex) => 3
console.log(reg.exec(str)) => ['34', index: 4, input: 'q12q34r', groups: undefined]
console.log(reg.lastIndex) => 6
console.log(reg.exec(str)) => null
console.log(reg.lastIndex) => 0
在最后没有内容捕获的时候会返回一个null,lastIndex也会恢复默认值值0,说明我们可以循环捕获所有的内容。判断返回值是否为null结束循环
function execAll(str = '', reg) {
let con = reg.exec(str)
if (!reg.global) return con
let res = []
while(con) {
res.push(con[0])
con = reg.exec(str)
}
return res
}
console.log(execAll('q12q34r', /\d+/g)) => ['12', '34']
2、贪婪性:正则的每一次匹配都是按照最长的的结果进行匹配捕获的,比如
'2022年1月20日'.match(/\d+/g) => ['2022', '1', '20']
但是20,202也是数字符合要求的,正则就会默认捕获最长的2022
如何解贪婪性:在量词元字符后面添加一个?即可(这样会按照最短的结果来获取)
'2022年1月20日'.match(/\d+?/g)
=> ['2', '0', '2', '2', '1', '2', '0']
这里总结下?在正则中的作用
1、左边不是量词元字符:本身代表量词元字符出现0到一次
2、左边是量词元字符:取消捕获的贪婪性
3、(?:) 只匹配不捕获
4、(?=) 正向预查
5、(?!) 反向预查
捕获的方法
1、正则RegExp.prototype上的方法test,exec
2、字符串String.prototype上的方法match,replace,split
exec
exec输出的结果是null或者一个数组:
第一项:大正则捕获的结果
其余项:小分组捕获的结果
index: 大正则捕获的内容在字符串中的起始索引
input: 原始字符串
缺点:每次执行只能捕获一次结果,不能一次性匹配所有的结果,而且因为正则的懒惰性如果没有加修饰符g永远只能匹配第一个,其余的根本捕获不到。如果添加了g则会更新lastIndex的值循环可以得到所有的结果
优点:可以捕获大正则的内容也可以捕获小分组的内容,可以根据需要获得想要的所有想要的结果
const reg = /^(\d{4})年(\d{1,2})月(\d{1,2})日$/
console.log(reg.exec('2022年1月28日'))
=> ['2022年1月28日', '2022', '1', '28', index: 0, input: '2022年1月28日', groups: undefined]
const reg = /\d+/g
const str = 'q12q34r'
console.log(reg.exec(str)) => ['12', index: 1, input: 'q12q34r', groups: undefined]
test
test本来时校验字符串是否符合规则,但是也可以捕获
这个主要是利用RegExp.9: 获取当前本次正则匹配后,第一个到第九个分组信息
这个方法不是很常用,主要是挂在了RegExp上,如果有其他的正则出现,那么结果就会被替换
const reg = /^(\d{4})年(\d{1,2})月(\d{1,2})日$/
reg.test('2022年1月28日')
console.log(RegExp.$1) => 2022
console.log(RegExp.$2) => 1
console.log(RegExp.$3) => 28
字符串中的方法
match
把所有和正则匹配到的内容都捕获到
和exec对比:在多次匹配时可以一次捕获所有结果,但是小分组匹配的信息无法获取
const reg = /(\d+)/g
const str = 'q12q34r'
console.log(str.match(reg)) => => ['12', '34']
replace
字符串中实现替换的方法,大部分时候都是和正则一起使用的
在不用正则的情况下执行一次只能替换一个,配合正则就可以一次替换完成多个
对时间字符串进行处理
const reg = /(\d{4})-(\d{1,2})-(\d{1,2})/g
const str = '2022-1-22'
console.log(str.replace(reg, '$1年$2月$3日')) => 2022年1月22日
还可以使用回调函数处理
console.log(str.replace(reg, (...[, $1, $2, $3]) => `${$1}年${$2}月${$3}日`))
[str].replace([reg], Function)
1、这种方式能匹配几次函数就会执行几次
2、Function中的参数信息和exec捕获的内容一致,第一项是大正则匹配的内容,后面是小正则匹配的内容
3、在函数中返回什么就把当前的大正则匹配的内容替换成什么
单词首字母大写
const reg = /\b([a-zA-Z])([a-zA-Z]*)\b/g
const str = 'good good study, day day up!'
console.log(str.replace(reg, (con, $1) => $1.toUpperCase() + con.substring(1)))
=> Good Good Study, Day Day Up!