创建正则表达式
字面量方式创建
// 两个斜杠之间是用来描述规则的元字符
let reg = /\d+/;
构造函数模式创建
// 两个参数:元字符字符串,修饰符字符串
let reg = new RegExp("\\d+");
字面量 VS 构造函数
-
构造函数因为传递的是字符串,\ 需要写两个才代表斜杠(需要转义);
let reg = /\d+/g; // 两个等价, reg = new RegExp("\\d+", "g");
-
如果正则中要包含某个变量的值,则需要使用构造函数的方式;
//字面量方式 let type = "baidu"; let reg = /^@"+type+"@$/; console.log(reg.test("@baidu@")); //=> false console.log(reg.test('@"""typeeee"@')); //=> true //构造函数方式 reg = new RegExp("^@" + type + "@$"); console.log(reg.test("@baidu@")); //=> true
正则相关 API
正则 API
API | 描述 |
---|---|
reg.test(str) |
验证某个字符串是否满足规则,返回 true 或 false |
reg.exec(str) |
执行匹配,返回一个数组,在未匹配到时会返回 null |
字符串 API
API | 描述 |
---|---|
str.match(reg) |
执行匹配,返回一个数组,在未匹配到时会返回 null |
str.matchAll(reg) |
执行查找所有匹配,返回一个迭代器 iterator |
str.search(reg) |
执行匹配,返回匹配到的位置索引,或者在失败时返回 -1 |
str.replace(reg) |
执行匹配,使用替换字符串替换掉匹配到的子字符串 |
str.split(reg) |
使用正则表达式或者一个固定字符串分隔一个字符串,返回一个数组 |
捕获的懒惰性
懒惰性的原因
每次处理只能捕获到一个符合正则规则的,但是默认情况下不论执行多少次,获取的结果永远是第一个匹配到的
lastIndex 默认情况下不会被改变
var reg = /abc/;
var s = "111abc111abc111";
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 0 true 0
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 0 true 0
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 0 true 0
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 0 true 0
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 0 true 0
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 0 true 0
解决懒惰性
只要设置了全局修饰符 g ,每次处理 lastIndex 都会改变
var reg = /abc/g;
var s = "111abc111abc111";
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 0 true 6
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 6 true 12
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 12 false 0
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 0 true 6
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 6 true 12
console.log(s, reg.lastIndex, reg.test(s), reg.lastIndex); // 111abc111abc111 12 false 0
取消贪婪性
贪婪就是尽量往多的匹配(默认),非贪婪就是尽量少的匹配;
在 量词元字符 后面设置 ? 可以取消贪婪性;
let str = "123abc456abc789";
// 贪婪性
let reg = /\d+/g;
console.log(str.match(reg)); // [ '123', '456', '789' ]
// 取消贪婪性,按最短匹配结果获取
reg = /\d+?/g;
console.log(str.match(reg)); // [ '1', '2', '3', '4', '5', '6', '7', '8', '9' ]
面试题
手写 reg.execAll
~function () {
function execAll(str) {
let result = []; // 捕获的结果
// ["2020", index: 8, input: "zhongguo2020yangfan2021qihang", groups: undefined]
let res = this.exec(str); //每一次捕获内容
// 第一件事:验证当前正则是否设置了全局修饰符,没有则不能进行循环捕获(陷入死循环)
if (!this.global) return this.exec(str);
while (res) {
// 把每一次捕获到的内容 res[0] 放到数组中
result.push(res[0]);
// 只要捕获结果不为 null,继续捕获
res = this.exec(str);
}
return result.length === 0 ? null : result;
}
RegExp.prototype.execAll = execAll;
}();
let str = "zhongguo2020yangfan2021qihang";
let reg = /\d+/g;
console.log(reg.execAll(str)); //=> ["2020", "2021"]
// 字符串的 match 已经实现该功能
console.log(str.match(reg)); //=> ["2020", "2021"]
leetcode🧑💻 1007. 行相等的最少多米诺旋转
上一篇