零基础学习推荐: https://juejin.cn/post/6844903845227659271
正则表达式手册: http://tool.oschina.net/uploads/apidocs/jquery/regexp.html
1. 元字符汇总
分组与回溯引用:
元字符 | 描述 |
---|---|
(pattern) | ()会把每个分组里的匹配的值保存起来,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推 |
(?:pattern) | (?:) 表示非捕获分组,和捕获分组唯一的区别在于,非捕获分组匹配的值不会保存起来; |
\1或\2等 | 表示重复正则第一个(或第二个)圆括号内匹配到的内容 |
注: (?:pattern) 在使用 "或" 字符 (|) 来组合一个模式的各个部分很有用。例如,'industr(?:y|ies)' 就是一个比 'industry|industries'更简略的表达式。因为我们单独存储下 “y” 或者 “ies” 没有什么意义
2. 正则表达式在JS中的使用
2.1 基本用法
let reg1 = /asd/;
let reg2 = new RegExp("asd","g");//匹配方法 匹配模式
typeof /asd/;//object
/as/.test("asd");//true
/asd/.test("assd");//false
/asd/.exec("asd");
//["asd", index: 0, input: "asd", groups: undefined]
/asd/.exec("assd");//null
在exec中匹配到了就会返回一个数组对象,数组对象中第一项是第一个满足匹配得字符串,第二项得是满足匹配开始得下标。第三项是被匹配得输入。groups是命名捕获组。
2.2 配合字符串方法使用
字符串String具有match和replace和search和split方法
"asd".match("as");//["as", index: 0, input: "asd", groups: undefined]
"asd".match(/as/);//["as", index: 0, input: "asd", groups: undefined]
//没有就是null
"asd".replace(/as/,"sa");// "sad" 不会改变原字符串,没匹配就不变
"asd".search(/dd/);//-1 返回第一个匹配得位置下标,没有就-1
"asd".search(/sd/);//1
"asd".split(/s/);//["a", "d"];
replace配合正则使用详解
replace()方法的第二个参数可以是一个文本,也可以是一个函数,在只有一个匹配项(即与模式匹配的字符串)的情况下,会向这个函数传递3个参数:模式的匹配项,模式匹配项在字符串中的位置和原始字符串。在正则表达式中定义了多个捕获组的情况下,传递给函数的参数依次模式的匹配项,第一个捕获组的匹配项,第二个捕获组的匹配项…,但最后两个参数仍然分别是模式的匹配项在字符串中的位置和原始字符串。
var toUrl = 'user/add?id=$18&t=update'.replace(/\$(\d+)/g, function (a, b, c, d) {
console.log(a); //$18,\$(\d+)匹配的模式匹配项
console.log(b); //18,(\d+)匹配的第一个捕获组的匹配项
console.log(c); //12,匹配项的位置
console.log(d); //user/add?id=$18&t=update,原始字符串
});
replace第二个参数若是一个函数:
- 匿名函数执行多少次,取决于正则能在字符串中捕获多少次
- 每次执行匿名函数,arguments值和通过exec捕获到的内容很类似
- return 返回值就是需要去替换的内容
var str = 'pku2016pku2017';
str = str.replace(/(\d+)/g, function () {
console.log(arguments);
// 第一次执行: ["2016", "2016", 7, "pkusoft2016pkusoft2017"]
//数组中各项解释:[正则匹配项,()中匹配的项,位置,原str]
// 第二次执行: ["2017", "2017", 18, "pkusoft2016pkusoft2017"]
// 返回的数组和执行exec返回的结果一致
return '0000';
});
console.log(str); // pkusoft0000pkusoft0000
3. 其它
3.1 命名组
具名组匹配在圆括号内部,在模式的头部添加问号尖括号和组名,就可以在exec方法上返回结果的groups上找到该组名。
let reg = /(?\d{4})-(?\d{2})-(?\d{2})/
"1999-01-24".match(reg) //注意groups
"1999-01-24".replace(reg, "$-$-$")//"24-01-1999"
3.2 exec 的迭代以及状态记录
当你使用全局匹配的时候,会有状态位值叠加
let str = "wowowo"
let reg = /wo/g
console.log(reg.exec(str)) // ["wo", index: 0, input: "wowowo", groups: undefined]
console.log(reg.exec(str)) // ["wo", index: 2, input: "wowowo", groups: undefined]
console.log(reg.exec(str)) // ["wo", index: 4, input: "wowowo", groups: undefined]
console.log(reg.exec(str)) // null
console.log(reg.exec(str)) // ["wo", index: 0, input: "wowowo", groups: undefined]