正则表达式的运用
字符串中的方法加上正则表达式威力更强,例如split、replace
对字符进行增删改查
下面通过一个小栗子,让你觉得正则表达式真香~
查找一个字符串中的所有数字,如果不用正则表达式:
let str = 'gvx543654gv3565423vgv'
//[...str]将字符串转化为数组
let nums = [...str].filter(item => Number.isNaN(parseInt(item))).join("")
// 5436543565423
使用正则表达式:
let str = 'gvx543654gv3565423vg@v'
// match:匹配
//字符串的match方法接收一个正则表达式作为参数,返回字符串由正则表达式处理过的结果
str.match(/\d/g).join("") // 5436543565423
创建正则表达式的方式:
一、字面量的形式:
let str = 'gvx543654gv3565423vg@v'
// console.log(/@/.test(str)) // true 检测字符串中是否有@ ,但是这种方式中,//里不能写变量
let a = 'vg'
console.log(eval(`/${a}/`).test(str)) // true eval中的字符串可以被当作js表达式执行
二、对象的形式:
let str = 'gh2667@vxv'
// let reg = new RegExp('@','g')
let a = '@' // \\w 字母数字下划线 \\d 数值
let reg = new RegExp(a,'g') // 对象形式的正则可以接受变量
console.log(reg.test(str)) // true 检测str中是否有@
给定一个字符串,让这个字符串随着用户的输入,相应的字母或数字变红:
<body>
<div id="changeColor">zbc123@@14</div>
<script>
let con = prompt("请输入要检测的内容,支持正则")
let reg = new RegExp(con, 'g')
let changeColor = document.getElementById('changeColor')
changeColor.innerHTML = changeColor.innerHTML.replace(reg, search => { return `<span style="color:red">${search}</span>` })
console.log(con) // 接到输入的值
console.log('qe.r'.replace(/\w/g, '@')) //将'qe.r'中的字母数字下划线都替换成@
</script>
</body>
选择符的使用
let str = 'gh2667@vxv'
// console.log(/6671|@/.test(str)) // true 判断str中是否有6671或@,满足一个条件就返回true
let num = '010-9999999'
console.log(/010|020\-\d{7,8}/.test(num)) // true
// \d表示数字,限制数字的位数,7~8位 ,-有特殊的意义,所以我们需要转义一下,使用\转义
// 但是像上面一样写有问题,我们把9999999删掉还是返回true,改进:
console.log(/010\-\d{7,8}|020\-\d{7,8}/.test(num)) // true 左右都要完整的电话号
// 上述\-\d{7,8}是重复的,使用原子组改进:
console.log(/(010|020)\-\d{7,8}/.test(num)) // true 左右都要完整的电话号
// 上述还是不严谨,'abc010-9999999'也能匹配上,所以我们要加上限制:
num = '^010-9999999$'
原子表和原子组中的选择符
// 原子表:() 原子组:[]
let reg = /[12344]/
let str = 'h2hcbhb'
console.log(str.match(reg))
//[ '1', index: 1, input: 'h1hcbhb', groups: undefined ]
// 只要str中有一个符合条件就能匹配上,一个都不符合返回null
let reg2 = /(12|34)/ // 12是一个整体,34是一个整体,只有整体匹配了才能匹配
console.log(str.match(reg2)) // null str = 'h12hcbhb'才能匹配上
转义
let price = '23.34'
// \d:0~9的数字 +:一个或多个数值
console.log(/\d+.\d+/.test(price)) // true 但是有问题,price = '23@34'还是true
// .换行外任何字符, .普通的点
console.log(/\d+\.\d+/.test(price)) // true 加了\对.进行转义 d也是普通字符串,加了\表示数值
let reg = new RegExp(/\d+\.\d+/) // true
//但是 reg = new RegExp('/\d+\.\d+/') 就不准确了,这相当于d+.d+了
reg = new RegExp('/\\d+\\.\\d+/') // true 准确了,使用了转义
console.log(reg.test(price))
let url = "https://www.wky.com"
console.log(/https?:\/\/\w+\.\w+\.+\w/.test(url)) // ?表示有s也许无s也行,//在正则中表示边界符,所以我们用\转义就成了\/\/
//www 任何字符,我们可以使用\w ; . 用 \.表示; wky 任何字符 \w ; . 用 \.表示;
字符边界约束
let str = 'vzx23vgf32a'
console.log(/\d/.test(str)) // true \d代表数值 str中但凡有个数字就满足
console.log(/^\d/.test(str)) // false ^表示以数字开始; str = 3vgf就为true
console.log(/^\d$/.test(str)) // false ^表示以数字开始,$表示以数字结束; str = 2就为true
判断用户输入是否为3~6位的字母:
<input name="user"></input>
<span></span>
<script>
document.
querySelector('[name="user"]').
addEventListener('keyup', function () {
// let flag = this.value.match(/[a-z]{3,6}/) // 只能输入3~6位的字母,但是有问题,只要超过3位都是成立
let flag = this.value.match(/^[a-z]{3,6}$/) // 加上边界限制就精确判断3~6位字母了
console.log(flag)
document.querySelector('span').innerHTML = flag ? "正确" : "错误"
})
</script>
数值与空白元字符
let str = 'syg35dd22'
console.log(str.match(/\d/)) // [ '3', index: 3, input: 'syg35dd22', groups: undefined ]
console.log(str.match(/\d\d/)) // [ '35', index: 3, input: 'syg35dd22', groups: undefined ]
console.log(str.match(/\d\d\d/)) // null
console.log(str.match(/\d/g)) // [ '3', '5', '2', '2' ]
console.log(str.match(/\d+/g)) // [ '35', '22' ] + 匹配一个或多个
let str = '张三:120-65625556; 李四:204-62681827'
console.log(str.match(/\d{3}-\d{8}/)) // ['120-65625556', index: 3, ......]
console.log(str.match(/\d{3}-\d{8}/g)) //[ '120-65625556', '204-62681827' ]
// \d : 数字 \D : 除了数字 + : 一个或多个
console.log(str.match(/\D/)) // [ '张', index: 0,.......]
console.log(str.match(/\D+/)) // [ '张三', index: 0,.......]
console.log(str.match(/\D/g)) // ['张', '三', ':','-', ';', '李', '四', ':', '-' ]
console.log(str.match(/\D+/g)) // [ '张三:', '-', ';李四:', '-' ]
str = '张三:120-65625556; 李四:204-62681827'
// []里写的我都要,写啥要啥
console.log(str.match(/[\d:;-]/g)) //[':', '1', '2', '0', '-', '6', '5', '6', '2', '5', '5', '5','6', ';', ':', '2', '0', '4', '-', '6', '2', '6', '8', '1', '8', '2', '7']
console.log(str.match(/[\d:;-]+/g)) //[ ':120-65625556;', ':204-62681827' ]
// 在[]里写^表示方括号里写的我都不要
console.log(str.match(/[^\d:;-]+/g)) //[ '张三', '李四' ]
// \s :空白
console.log(/\s/.test(' ')) //true
console.log(/\s/.test('\n')) //true 换行符
// \S 除了空白
console.log(/\S/.test('tew')) //true
console.log(/\S/.test(' ')) //false
console.log(/\S/.test(' bvcx ')) //true 因为它会往后继续找,找不是空白的就返回true了
w与W元字符
// \w : 字母、数字、下划线 也就是说他囊括了 \d
let str = 'bhbs_sd23-v21v-'
console.log(str.match(/\d+/)) // [ '23', index:7 ,........]
console.log(str.match(/\w+/)) // ['bhbs_sd23', index: 0, ........]
console.log(str.match(/\w+/g)) // [ 'bhbs_sd23', 'v21v' ]
let email = '^&%...1946376553@qq.com'
console.log(/\w+@\w+\.\w+/.test(email)) // true 这样不严谨, email = '126g%%……1946376553@qq.com'也为true
console.log(/^\w+@\w+\.\w+$/.test(email)) // false 因为加上了边界限定
// \W : 除了数字、字母、下划线
email = '^&%...1946376553@qq.com'
console.log(email.match(/\W+/g)) // [ '^&%...', '@', '.' ]
// 用户名需求:以字母开始,后跟字母数字下划线,用户名长度在5~10位
console.log(/^[a-z]\w{4,9}$/.test('sdr7sw')) // true 因为[a-z]已经占了一位了,所以是{4,9}
// 用户名需求:以字母开始,后跟字母数字下划线和-,不区分大小写,用户名长度在5~10位
console.log(/^[a-z][\w-]{4,9}$/i.test('sdr7sw')) // true 因为[a-z]已经占了一位了,所以是{4,9}
点元字符的使用
// \d:数值 \w :数字字母下划线 . : 除了换行符之外的所有字符
let str = 'vsfc#%$ccsgc&v789.,.;。,'
console.log(str.match(/./)) // [ 'v', index: 0,.........]
console.log(str.match(/.+/)) // [ 'vsfc#%$ccsgc&v789.,.;。,', index: 0,inpu.....]
console.log(str.match(/.+/g)) //[ 'vsfc#%$ccsgc&v789.,.;。,' ]
// 需求:匹配一个网址
let net = 'https://www.baidu.com'
console.log(/https?:\/\/\w+\.\w+\.\w+/.test(net)) // true
//https直接写,s可有可无所以加? :直接写,//需要转义,\w+匹配一个或多个字母数字下划线,点(.)也需要转义...
// 需求:在一堆字符串中,找出里面的所有网址
net = 'https://www.baidu.com&Bbshbhttps://www.baidu.comGVV67https://www.baidu.com三个vhttps://www.baidu.com'
console.log(net.match(/https?:\/\/\w+\.\w+\.\w{0,3}/g)) // [ 'https://www.baidu.com', 'https://www.baidu.com', 'https://www.baidu.com', 'https://www.baidu.com' ]
// com只要3个字母,所以{0,3}
let str = `
vsfc#%$ccsgc
&v78-9
`
console.log(str.match(/.+/)) // ['vsfc#%$ccsgc', index: 1,...] 因为再遇到换行符他就停了
// \s:把相应字符串视为单行 相当于把换行符当作普通空白字符串来使用了 这样.也能匹配换行符了 .就无敌了!!!!
console.log(str.match(/.+/s)) // ['\nvsfc#%$ccsgc\n&v78-9 \n', index: 0,......]
let tel = '010 - 68762366'
console.log(tel.match(/\d+ - \d+/)) // ['010 - 68762366',index: 0,...]空格也是普通字符,只是我们人看不见,对计算机来说它和abc是一样的,我们可以直接写在正则中
// 但是也可以用\s来代替
console.log(tel.match(/\d+\s-\s\d+/)) // ['010 - 68762366',index: 0,...]
如何精巧的匹配所有字符
let str = 'wky'
// []:匹配str中满足[]条件的所有内容
console.log(str.match(/[sbahw]/)) // [ 'w', index: 0, inp.....]
// 不加[]表示完整的匹配一段内容
console.log(str.match(/sbahw/)) // null
let spanStr = `
<span>
https://www.wky.com
</span>
`
// \s:空白字符 \S:除了空白字符,[\s\S] : 所有字符 [\d\D]也行
console.log(spanStr.match(/<span>[\s\S]+<\/span>/)) // [ '<span>\nhttps://www.wky.com\n</span>', index: 1, input: '\]
console.log(spanStr.match(/<span>.+<\/span>/s))// [ '<span>\nhttps://www.wky.com\n</span>', index: 1, input: '\]
i与g模式修正符
let str = 'vzvSGfscf1F2'
console.log(str.match(/s/i)); // [ 'S', index: 3,...] /i不区分大小写
console.log(str.match(/f/g)); //[ 'f', 'f' ] /g全局匹配
console.log(str.match(/s/ig)); //[ 'S', 's' ] /ig不区分大小写且全局匹配 ig gi顺序随便
console.log(str.replace(/f/ig,'@')); //vzvSG@sc@1@2 将str中的f不区分大小写全都替换成@
m多行匹配修正符
let str = `
#1 js,22元 #
#2 java,0.345yuan #
#3 python,0.21 # wky
#4 node,2301 #
`
console.log(str.match(/\s*#\d+\s+.+\s+#$/gm)); // [ '\n#1 js,22元 #', '\n#2 java,0.345yuan #', '\n#4 node,2301 #' ]
let res = str.match(/\s*#\d+\s+.+\s+#$/gm).map(item => {
item = item.replace(/\s*#\d+\s*/, '') // js,22元 # ; java,0.345yuan ; #node,2301 #
.replace(/#/, '') // js,22元 ; java,0.345yuan ; node,230
console.log(item)
// 数组解构
let [name, price] = item.split(',') // item.split(','): [ 'js', '22元 ' ] ; [ 'java', '0.345yuan ' ].... ;
return { name, price } // 对象的key和value一样,简写
})
汉字与字符属性
sc={Han}会匹配到偏旁部首 片假字
let str = `sbhhd我是中文sjb`
console.log(str.match(/\p{sc=Han}/ug)) // [ '我', '是', '中', '文' ]
lastIndex属性
let str = `sbhhd我是中文sjb`
console.log(str.match(/\w/)) // [ 's', index: 0, input: 'sbhhd我是中文sjb',...]
console.log(str.match(/\w/g)) // ['s', 'b', 'h','h', 'd', 's', 'j', 'b']属性丢失了
let reg = /\w/g // 不把正则提出来或不加g,exec永远获取到的都是s,不会往下走
console.log(reg.lastIndex) // 0
console.log(reg.lastIndex) // 0
console.log(reg.exec(str)) // [ 's', index: 0, input: 'sbhhd我是中文sjb',
console.log(reg.exec(str)) // [ 'b', index: 1, input: 'sbhhd我是中文sjb',
console.log(reg.exec(str)) // [ 'h', index: 2, input: 'sbhhd我是中文sjb',
console.log(reg.lastIndex) // 3 所以每调用一次execlastIndex就会++
while(res = reg.exec(str)){
console.log('res: ', res);
}
// res: [ 'h', index: 3, input: 'sbhhd我是中文sjb', groups: undefined ]
// res: [ 'd', index: 4, input: 'sbhhd我是中文sjb', groups: undefined ]
// res: [ 's', index: 9, input: 'sbhhd我是中文sjb', groups: undefined ]
// res: [ 'j', index: 10, input: 'sbhhd我是中文sjb', groups: undefined ]
// res: [ 'b', index: 11, input: 'sbhhd我是中文sjb', groups: undefined ]
有效率的y模式
g:当不是要找的值,直接跳过即可 y:得一直连续的满足条件
let str = `hhh`
let reg = /h/y // 不把正则提出来或不加g,exec永远获取到的都是s,不会往下走
console.log(reg.lastIndex) // 0
console.log(reg.lastIndex) // 0
console.log(reg.exec(str)) // [ 'h', index: 0, input: 'sbhhd我是中文sjb',
console.log(reg.exec(str)) // [ 'h', index: 1, input: 'sbhhd我是中文sjb',
console.log(reg.exec(str)) // [ 'h', index: 2, input: 'sbhhd我是中文sjb',
console.log(reg.lastIndex) // 3 所以每调用一次execlastIndex就会++
str = `hhsahd`
reg = /h/y
console.log(reg.lastIndex) // 0
console.log(reg.lastIndex) // 0
console.log(reg.exec(str)) // [ 'h', index: 0, input: 'sbhhd我是中文sjb',
console.log(reg.exec(str)) // [ 'h', index: 1, input: 'sbhhd我是中文sjb',
console.log(reg.exec(str)) // null
console.log(reg.exec(str)) // [ 'h', index: 0, input: 'sbhhd我是中文sjb',
console.log(reg.lastIndex) // 1
let str = `我的qq号:6457412145,7465111,982333225,欢迎加入,网址:jhsbbnx.com`
let reg = /(\d+),?/y // 不把正则提出来或不加g,exec永远获取到的都是s,不会往下走
console.log(reg.lastIndex) // 0
console.log(reg.lastIndex) // 0
console.log(reg.exec(str)) // null
console.log(reg.exec(str)) // null
console.log(reg.exec(str)) // null
console.log(reg.lastIndex) // 0
reg.lastIndex = 6
console.log(reg.exec(str)) //['6457412145,','6457412145',index:6....]
console.log(reg.exec(str)) // ['7465111,','7465111,',index:17....]
console.log(reg.exec(str)) // ['982333225,','982333225,',index:25....]
console.log(reg.lastIndex) // 35
let str = `我的qq号:6457412145,7465111,982333225,欢迎加入,网址:jhsbbnx.com`
let reg = /(\d+),?/y // 不把正则提出来或不加g,exec永远获取到的都是s,不会往下走
reg.lastIndex = 6 //千万别忘了要设置index开始的位置,不然匹配不到,就是null,因为y要连续才有效
let arr = []
while(res = reg.exec(str)){
console.log(res)
arr.push(res[1])
}
console.log(arr); // [ '6457412145', '7465111', '982333225' ]
原子表基本使用
let str = `vgzs5+5sx`
let reg = /se/g // 不把正则提出来或不加g,exec永远获取到的都是s,不会往下走
console.log(str.match(reg)); // null str中要有s和e连着的字符串才得行
reg = /[se]/g //有s或e都行
console.log(str.match(reg)); // [ 's', 's' ]
let data= '2020-10-10'
reg = /\d{4}-\d{1,2}-\d{1,2}/g
console.log(data.match(reg)); // [ '2020-10-10' ]
reg = /^\d{4}-\d{1,2}-\d{1,2}$/g // 严格以数字开头,数字结尾
console.log(data.match(reg)); // [ '2020-10-10' ]
data= '2021/10/1'
reg = /^\d{4}([-\/])\d{1,2}\1\d{1,2}$/g // 以-作为分割或者/作为分割都行,\1 : 前一个以什么分割后一个也要一样,不能出现2020-10/1的格式
console.log(data.match(reg)); // [ '2021/10/1' ]
区间匹配
let str = `2021vxfcx`
let reg = /[0-9]/g // 取到str中0-9的数 注意只能升序不能降序
console.log(str.match(reg)); // [ '2', '0', '2', '1' ]
reg = /[a-z]/
console.log(str.match(reg)); //[ 'v', index: 4,.....]
reg = /[a-z]/g
console.log(str.match(reg)); //[ 'v', 'x', 'f', 'c', 'x' ]
reg = /[a-z]+/g
console.log(str.match(reg)); //[ 'vxfcx' ]
需求:输入框中只能输入以字母开头、以字母结尾,不区分大小写,4~7位的内容
<input name="change" />
<script>
let input = document.querySelector(`[name="change"]`)
input.addEventListener('keyup', function () {
console.log(this.value.match(/^[a-z]\w{3,6}$/i))
})
</script>
排除匹配
let str = `2021vxfcx`
let reg = /[^vx]+/g // 除了vx其他的都匹配
console.log(str.match(reg)); // [ '2021', 'fc' ]
str = `张三:120-65625556; 李四:204-62681827`
reg = /[^:\d-;]+/g // 除了:数字 - ;其他的都要
console.log(str.match(reg)); // [ '张三', ' 李四' ]
普通初学者容易犯的错误:
str = `(张三:120-65625556); 李四:204-62681827`
let reg = /[()]+/g // 现在的()就是普通的字符串,没有原子组的含义了,除非把它放到[]的外面,点也一样,只是普通字符串
console.log(str.match(reg)); // [ '(', ')' ]
str = `
张三:120-65625556; 李四:204-62681827
`
let reg = /[\s\S]/g // .能匹配所有但不能匹配换行符,但/s/S真正的匹配所有
console.log(str.match(reg));// [ '\n', '张', '三', ':', '1', '2', '0', '-', '6', '5', '6', '2','5', '5', '5'...]
原子组
let str = `
<h1>vsahgvytdv</h2>
<h6>vsahgvytdv</h6>
`
let reg = /<(h[1,6])>[\s\S]*<\/\1>/gi
// \s后面是{1,6},但是匹配的具体符号后面是[1,6],这容易混淆
// 前面有了原子表后面 才能用\1,表示和前面原子表的内容一样,
// reg = /<(h[1,6])>([\s\S])*<\/\1>/gi 也行
console.log(str.match(reg));// [ '<h6>vsahgvytdv</h6>' ]
匹配邮箱
let str = '441cdx-44981@qq.com'
console.log(str.match(/\w+\-\w+@\w+\w+\.(com|cn|org|net)/g)); //[ '441cdx-44981@qq.com' ]
console.log(str.match(/[\w-]+@[\w-]+\.(com|cn|org|net)/g)); //[ '441cdx-44981@qq.com' ]
// 但是新浪的邮箱:sggywbdvvew@sina.qq.cn的形式
str = 'sggywbdvvew@sina.qq.cn'
console.log(str.match(/[\w-]+@[\w-]+\.[\w-]+\.(com|cn|org|net)/g)); //[ 'sggywbdvvew@sina.qq.cn' ]
console.log(str.match(/[\w-]+@([\w-]+\.)+(com|cn|org|net)/g)); //[ 'sggywbdvvew@sina.qq.cn' ]
原子组引用完成替换操作
如果你某个内容要拿出来,你就把它变成一个组
let str = `
<h1>bvxbxuy</h1>
<span>8784645</span>
<h5>bxgvsit</h5>
`
console.log(str.match(/<(h\d{1,6})>\w+<\/\1>/gi)); //[ '<h1>bvxbxuy</h1>', '<h5>bxgvsit</h5>' ]
console.log(str.replace(/<(h\d{1,6})>([\s\S]+)<\/\1>/gi, `<p>$2</p>`)); // <p>bvxbxuy</p><span>8784645</span> <p>bxgvsit</p>
// $1 : h1、h5
// $2 : bvxbxuy、bxgvsit
let reg = /<(h\d{1,6})>([\s\S]+)<\/\1>/gi
let res = str.replace(reg, (p0, p1, p2, p3 ) => {
// p0:就是正则匹配的完整的字符串 //[ '<h1>bvxbxuy</h1>', '<h5>bxgvsit</h5>' ]
// p0 后面的参数就是原子组,p1就是 第一个(),p2就是第二个(),如果有嵌套就从第一个(开始数,嵌套在外的先数,在里的后数
return `<p>${p2}</p>`
})
console.log(res)
// <p>bvxbxuy</p> <span>8784645</span> <p>bxgvsit</p>
嵌套分组与不记录分组
let str = `https://www.baidu.com
http://wky.com
`
console.log(str.match(/https?:\/\/\w+\.\w+\.(com|cn|org)/g));
// // 需求:https:// 不要,只要域名,用括号把域名部分包起来 如下
console.log(str.match(/https?:\/\/(\w+\.\w+\.(com|cn|org))/g));
// //以上 0是整个内容 第一个出现的括号(是1,然后是2
// // 需求 去除第二个括号,让\2用不了:在括号里加(?: 如下
console.log(str.match(/https?:\/\/(\w+\.\w+\.(?:com|cn|org))/g));
// // 有些域名没有www 我们把www正则部分包起来,加? 修改正则如下
console.log(str.match(/https?:\/\/((\w+\.)?\w+\.(?:com|cn|org))/));
// ['https://www.baidu.com','www.baidu.com','www.',index: 0, input: 'ht...]
// 上面是从0开始数的,第0个表示匹配的完整的字符串,第一个是表示第一个(里匹配的内容,第二个是表示第二个(里匹配的内容 ; 所以下面while循环的时候,我们取res[1]
// 如果不想让他记录()的话,在()里加上?:即可 修改如下
console.log(str.match(/https?:\/\/((?:\w+\.)?\w+\.(?:com|cn|org))/)); // ['https://www.baidu.com','www.baidu.com',index: 0, input: 'htt...]
// 需求: 将str中所有域名都提出来
let urls = []
let reg = /https?:\/\/((?:\w+\.)?\w+\.(?:com|cn|org))/g // 不把reg提出来while循环就不会停。。。因为exec永远不会为null
while ((res = reg.exec(str))){
urls.push(res[1])
}
console.log(urls) // [ 'www.baidu.com', 'wky.com' ]
批量使用正则完成密码验证
<input type="text" name="userPassword" />
// 需求:密码必须以字母或数字开头,不区分大小写,密码中必须包含至少一个大写字母和一个数字
<script>
let input = document.querySelector(`[name="userPassword"]`)
input.addEventListener('keyup', function (e) { // keyup:键盘抬起,mouseup鼠标抬起
let value = e.target.value // 拿到用户输入的值
let reg = [/^[a-z0-9]{5,7}$/i, /[A-Z]/, /\d/] // 密码必须以字母或数字开头,不区分大小写 ;密码中必须包含至少一个大写字母 ;密码中必须包含至少一个数字
let state = reg.every(item => item.test(value)) // 字符串必须满足reg中正则的所有条件才能返回true
console.log(state)
})
</script>
禁止贪婪
let str = `wkkkkky`
// +:表示一个或多个,加了问号就禁止贪婪,趋向于少的一方:一个,*:表示零个或多个,加了问号就禁止贪婪,趋向于少的一方:零个
console.log(str.match(/wk+/g)) // [ 'wkkkkk' ]
console.log(str.match(/wk+?/g)) // [ 'wk' ]
console.log(str.match(/wk*?/g)) // [ 'w' ]
console.log(str.match(/wk??/g)) // [ 'w' ] 禁止问号贪婪
console.log(str.match(/wk{2,}/g)) //[ 'wkkkkk' ]
console.log(str.match(/wk{2,}?/g)) //[ 'wkk' ] 趋向于2
禁止贪婪实践:
<main>
<span>vxgsffstf</span>
<span>wky.com</span>
<span>nbsbsc.com</span>
</main>
<script>
let main = document.querySelector(`main`)
let reg = /<span>([\s\S]+?)<\/span>/gi // 如果不加?就会把3个span一次性匹配完,而我们需要它一次匹配一个
main.innerHTML = main.innerHTML.replace(reg, (v, p1) => { // p1 第一个原子组所匹配的内容
return `<h3 style="color:red">有趣-${p1}<h3>`
})
</script>
结果:
把?去掉的结果:
使用matchAll完成全局匹配
需求:将span标签里的内容提取出来
<body>
<div class="main">
<span>bhbudjsdx</span>
<span>wky.com</span>
<span>学正则</span>
</div>
</body>
<script>
const main = document.querySelector('.main')
let reg = /<(span)>([\s\S]+?)<\/\1>/g // 这里必须加?禁止贪婪,否则匹配就会超出span之外的
// console.log(main.innerHTML.match(reg)); //["<span>bhbudjsdx</span>\n <span>wky.com</span>\n <span>学正则</span>"]
let res = main.innerHTML.matchAll(reg); //RegExpStringIterator {} 一个迭代对象
let contents = []
for (const item of res) {
contents.push(item[2]) // 如果是item[1],content就是["span", "span", "span"]
}
console.log('contents: ', contents); // ["bhbudjsdx", "wky.com", "学正则"]
</script>
使用exec完成全局匹配
const main = document.querySelector('.main')
let reg = /<(span)>([\s\S]+?)<\/\1>/g // 这里必须加?禁止贪婪
let contents = []
while (res = reg.exec(main.innerHTML)) {
contents.push(res[2])
}
console.log('contents: ', contents); // ["bhbudjsdx", "wky.com", "学正则"]
字符串的search和match方法
let str = `wkkkkky`
console.log(str.match(/w/g)) // [ 'w' ]
console.log(str.search(/w/g)) // 0 返回相应字符在字符串中的索引
字符串的matchAll与split
有些结果要用matchAll获得,但是有些结果使用split也行
let date = '2021/10/10'
console.log(date.split(/[-\/]/)) // [ '2021', '10', '10' ]
date = '2021-10-10'
console.log(date.split(/[-\/]/)) // [ '2021', '10', '10' ]
$在正则替换中的使用
let num = '(010)-44444444 (020)-99999999'
let reg = /\(\d{3,4}\)-\d{7,8}/g
console.log(num.match(reg)) // [ '(010)-44444444', '(020)-99999999' ]
reg = /\((\d{3,4})\)-(\d{7,8})/g
console.log(num.replace(reg,"$1-$2")); // 010-44444444 020-99999999
为什么写博客?
有人说最好的学习方法就是写一本书。其实,要想把知识掌握牢固,归根到底就是用起来。写书或者说写作是一种很好的以教为学的手段,写博客也一样。
持续更新…