js正则
正则 RegExp
字符模板:*
0次到多次、+
1次到多次、?
零次到一次;修饰符:g
全局匹配、i
不区分大小写;正则一般使用到五个方法:test、exec、match、replace、search
reg = new RegExp('0', 'g');// 等价于 reg= /0/g;
//在正则中使用变量
function reg(zz,yy) {
return new RegExp(zz, yy);
}
正则方法 test
reg.test(str) 返回 boolean 常用于判断字符串是否包含某种格式的字符串,是返回true,反之false;
类似的字符串也有个方法:str.includes('child_str') 返回 boolean 常用于判断字符串是否包含子字符串,是返回true,反之false;
正则方法 exec
reg.exec(str) 没匹配到返回null,如果匹配成功它就会返回一个(即使有全局g也只返一个)神奇的数组 ,为什么说他神奇:Array.isArray(reg.exec(str)) 返回true,所以真的是数组;但是它跟正常数组又不一样;一般数组有length属性 返回数组长度且只有一个length属性。但是exec()却多了三个属性:
- groups 捕获组
- index: 当前符合正则的下标(可能匹配到多个)
- input:匹配的对象 即 我们的str
捕获组文章下面会细说;input 就是我们需要匹配的字符串;index 下标,为当前匹配到的内容的首个字符的下标,如果正则没有修饰符g 那么 exec 返回的index 永远是0,如果有全局修饰符g,exec将从上一次返回的index开始向后匹配内容,所以重新开始时需要把 index 置为0;

// 不用去手动去修改index
// 每次遍历都会返回详细的匹配信息包括 捕获组
let arr = 0
while (arr !== null) {
arr = reg.exec(str)
}
字符串方法 match
在没有全局修饰符是 和 正则的exec 一模一样,返回一个神奇的数组,不同点在于有全局修饰符g的时候,返回一个正常的数组,只包含匹配的元素,没有捕获组、index、input;所以如果只想返回匹配到的对象而不想要详细的信息的话,可以选择使用match;

字符串方法 replace
字符串.replace(正则,新的字符串/回调函数)(在回调函数中,第一个参数指的是每次匹配成功的字符)
str.replace(reg1,"k")
// 参数是回调函数时 可以替换的同时统计字符串出现次数
str.replace(/12/g,(ele) => {
console.log(ele) // ele 为匹配到的值 12
if (ele < 3) sum++
});
字符串方法 search
str.search(reg) 返回第一个匹配到的字符串的第一个字符的下标,找到一个就不会继续找了(g没有作用);找不到返回-1,与search 类似的还有indexOf;
indexOf:某个指定的字符串值在字符串中首次出现的位置,如果没有找到返回-1。二者的区别是:search()的参数必须是正则表达式,而indexOf()的参数只是普通的字符串。indexOf()是比search()更加底层的方法。使用indexOf()查找具体字符时系统资源消耗更小,效率更高;
捕获组
- 普通捕获组:(Expression) 写正则的时候用()括起来的就是一个组 这个组没有名字 但每个组有下标(0是整个正则表达式)
- 命名捕获组:(?
Expression) 使用? 给这个组加个名字 (不仅仅有名字 它的下标还是在的)

(?:pattern)、(?=pattern)、(?!pattern)、(?<=pattern)、(?<!pattern)
- (?:pattern) 用括号的目的只是把bc包起来使用{}限制次数 如: /a(?:bc)
- (?=pattern) 后面是什么的 如:a[bc](? = 2) 匹配ab或ac后面有2的
- (?!pattern) 后面不是什么的 如:a[bc](? ! 2) 匹配ab或ac后面不是2的 跟(?=2)相反
- (?<=pattern) 正向肯定预查 前面是什么的 如:(?<=2)a[bc] 匹配a前面有2的
- (?!=pattern) 正向否定预查 前面不是什么的 如:(?!=2)a[bc] 匹配a前面没有2的
上面五个都不会进行存储供以后使用 即都不会形成捕获组,一般应用与 只是匹配的时候获取,并不需要把它匹配下来
// 匹配中括号中的内容
let str = '该文章涉及教育类图书【萍萍的家】学术类图书【三维曲线】'
let reg = /(?<=【)[^【】]*(?=】)/g
let arr = str.match(reg);
console.log(arr) // ['萍萍的家', '三维曲线']
// 至少一个大写 一个小写 一个数字 一个[$@%] 6个数
/^(?=.*[A-Z])(?=.*[a-z])(?=\D*\d)(?=.*[$@%])[\w$@%][6]$/
// 把字符串 等分 每三个换行
str.replace(/([\S,\s]{3})/g,`$&\n`)
捕获组的引用
var s2="11212112"
var r2=/(1)(2)\1\2/;
// var r2=/\1(1)(2)\1\2/; 在捕获组之前对捕获组引用无效 第一个\1 无效
console.log(r2.exec(s2)); // ['1212', '1', '2', index: 1, input: '11212112', groups: undefined]
- \1是对下标为1的分组匹配到的内容的引用注意是内容的引用 不是正则的引用;
- \2是对下标为2的分组匹配到的内容的引用
知识
匹配过的不再参与匹配
