创建正则表达式

字面量方式创建

// 两个斜杠之间是用来描述规则的元字符
let reg = /\d+/;

构造函数模式创建

// 两个参数:元字符字符串,修饰符字符串
let reg = new RegExp("\\d+");

字面量 VS 构造函数

  1. 构造函数因为传递的是字符串,\ 需要写两个才代表斜杠(需要转义);

    let reg = /\d+/g;
    // 两个等价,
    reg = new RegExp("\\d+", "g");
    
  2. 如果正则中要包含某个变量的值,则需要使用构造函数的方式;

    //字面量方式
    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) 验证某个字符串是否满足规则,返回 truefalse
reg.exec(str) 执行匹配,返回一个数组,在未匹配到时会返回 null

字符串 API

API 描述
str.match(reg) 执行匹配,返回一个数组,在未匹配到时会返回 null
str.matchAll(reg) 执行查找所有匹配,返回一个迭代器 iterator
str.search(reg) 执行匹配,返回匹配到的位置索引,或者在失败时返回 -1
str.replace(reg) 执行匹配,使用替换字符串替换掉匹配到的子字符串
str.split(reg) 使用正则表达式或者一个固定字符串分隔一个字符串,返回一个数组

捕获的懒惰性

懒惰性的原因

  1. 每次处理只能捕获到一个符合正则规则的,但是默认情况下不论执行多少次,获取的结果永远是第一个匹配到的

  2. 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

取消贪婪性

  1. 贪婪就是尽量往多的匹配(默认),非贪婪就是尽量少的匹配;

  2. 量词元字符 后面设置 ? 可以取消贪婪性;

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"]
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 创建正则表达式
    1. 1.1. 字面量方式创建
    2. 1.2. 构造函数模式创建
    3. 1.3. 字面量 VS 构造函数
  2. 2. 正则相关 API
    1. 2.1. 正则 API
    2. 2.2. 字符串 API
  3. 3. 捕获的懒惰性
    1. 3.1. 懒惰性的原因
    2. 3.2. 解决懒惰性
  4. 4. 取消贪婪性
  5. 5. 面试题
    1. 5.1. 手写 reg.execAll