一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情。
定义正则
定义正则有两种方式:
- new RegExp('a'): RegExp对象,参数就是我们想要制定的规则,这种方式适合规则是动态的
- /a/: 简写,但是不能动态定义规则
这两种方式有时候在写法上有些区别,比如在匹配空格时需要加转义字符\
/\s/ 这样写即可
new RegExp('\\s') 这里必须要加一个转义
正则表达式模式
方括号
元字符
数量匹配
- ? :匹配0或者1个
- * :匹配0个或者多个
- + :匹配1个或者多个
正则的方法
test
在字符串中查找符合正则的内容,若查找到返回true,反之返回false。
var str = '374829348791'
// \D代表非数字
var re = /\D/
if (re.test(str)) {
// 返回true,代表在字符串中找到了非数字。
console.log('不全是数字')
} else {
console.log('全是数字')
}
exec
和match方法一样,搜索符合规则的内容,并返回内容,格式为数组。
数组的第一项代表匹配的内容,第二项代表子项,即()里面匹配的内容。
如果想要全局匹配,首先var re = /test(\d+)/g, 表示全局匹配,然后不断的调用re.exec(testStr),它就会匹配下一个。
字符串使用正则的方法
search
在字符串搜索符合正则的内容,搜索到就返回出现的位置, 如果搜索失败就返回 -1。
在字符串中找字母b,且不区分大小写:
var str = 'abcdef';
var re = /B/i;
// var re = new RegExp('B','i'); 也可以这样写
console.log( str.search(re) ); // 1
match
在字符串中搜索符合规则的内容,搜索成功就返回内容,格式为数组,失败就返回null。
找出指定格式的所有数字,如下找到 123,54,33,879
var str = 'haj123sdk54hask33dkhalsd879';
var re = /\d+/g;
console.log( str.match(re) ); // [123,54,33,879]
每次匹配至少一个数字 且全局匹配 如果不是全局匹配,当找到数字123,它就会停止了,就只会弹出123。加上全局匹配,就会从开始到结束一直去搜索符合规则的。
如果没有加号,匹配的结果就是1,2,3,5,4,3,3,8,7,9并不是我们想要的,有了加号,每次匹配的数字就是至少一个了。
replace
查找符合正则的字符串,就替换成对应的字符串,返回替换后的内容。
stringObject.replace(regexp/substr, replacement)
replacement: 要么是一个替换文本的字符串,要么是一个生成替换文本的函数
敏感词过滤
var str = '我爱北京天安门,天安门上太阳升。'
var re = /北京|天安门/g
var str2 = str.replace(re, function (str) {
// 函数的第一个参数代表每次搜索到的符合正则的字符,
// 所以第一次str指的是北京 第二次str是天安门 第三次str是天安门
console.log('str', str)
var result = ''
for (var i = 0; i < str.length; i++) {
result += '*'
}
return result //所以搜索到了几个字就返回几个*
})
console.log(str2) //我爱*****,***上太阳升
特殊符号
- $&: 与正则相匹配的字符串
- 2,n: 匹配结果中对应的分组匹配结果
'abc'.replace(/b/, "$&123") // 'ab123c'
'sjn@163.com'.replace(/(.+)(@)(.*)/,"$2$1") // '@sjn'
'sjn@163.com'.replace(/(.+)(@)(.*)/,"$3$2$1") // '163.com@sjn'
案例
小驼峰转化为中划线
把abCd转化为ab-cd
'abCd'.replace(/[A-Z]/g, c => `-${c.toLocaleLowerCase()}`)
把中划线转化从小驼峰
const camelizeRE = /-(\w)/g
const str = 'name-space'
const str1 = str.replace(camelizeRE, (_, c) => {
console.log('_', _) // _s
console.log('c', c) // s 代表分组的内容
return c ? c.toUpperCase() : ''
})
console.log(str1)
/(?:^|\/)\.?\.$/
分析/(?:^|\/)\.?\.$/所表示的具体含义
.表示匹配任何字符,但是这里只想匹配点这个字符,所以加了反斜杠,进行转义()括号表示分组(?:)非捕获分组:也就是不会把分组的内容匹配出来- /^/ 匹配空;/^A/ 匹配开头的A;/[^A]/ 匹配除A以外的其他字符
这个正则所匹配的内容是/.. /.
拿到13px 9.5px里面的数字
const reg = /^(\d+(\.\d+)?)px$/
const arr = val.match(reg)
非捕获分组
密码包含数字,字母和特殊字符
const reg = /^.*(?=.{8,})(?=.*\d)((?=.*[A-Z])|(?=.*[a-z]))(?=.*[!@#$%^&*?\\(\\))]).*$/
正向先行断言 (?= ): 这是一个先行断言,用以说明圆括号内的表达式必须正确匹配。比如:/Java(?=:)/ 只能匹配Java且后面有冒号的。
(?=.*[!@#$%^&*?()]): 该断言表示,必须包括一个特殊字符。上述表达式中的10个特殊字符为键盘1,2...0的上档键字符,也可以添加别的特殊字符。
匹配千分位
function format(v) {
const reg = /\d{1,3}(?=(\d{3})+$)/g
return v.replace(reg, '$&,')
}
?=(\d{3}+)$,表示最后的数字是3个一组,即只有最后面的是数字是三个一组那么就是匹配上了。
var str = '1234567890'
首先最后三个数字是 234 567 890 前面是1,也就是当前面是1的时候,后面满足?=的条件,那么1就是合格的;
匹配完1之后,剩下的数字是'234567890',把2拿出来,剩下的是345 678 90 显然不满足?=的条件,那么接着匹配;
匹配23,后面的是 456 789 0 显然也不行;
匹配234,后面是567 890 满足?=的条件,所以234 是合格的;
直接继续匹配,最后只有1, 234, 567能满足要求,只要当前面的数字是1,234, 567的时候,后面的模式是满足的。
var str = '1234567890'
var reg = /\d{1,3}(?=(\d{3})+$)/g
str.match(reg) // [1, 234, 567]
匹配出来后,进行替换$&表示匹配替换的内容,也就是1 或者234 或者567, 那么在后面加个逗号就行了:
str.replace(reg, '$&,')
正则匹配有个特点,如果是全局匹配,如果第一次匹配上了,那么把匹配的值去掉,剩下的再进行匹配。
匹配空格换行
str.replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, '')
[\r\n]匹配回车和换行,/^\s+|\s+$/gm匹配空格。
推荐一个验证正则的网站:regexr.com/