一、正则的捕获

RegExp.prototype.exec()方法 exec()是正则上的一个方法,用来捕获复合规则的内容

1、正则捕获的懒惰性

  • 每次执行exec正则捕获时,只能捕获到第一次出现符合规则的内容,在不进行任何处理的情况下,再执行多次捕获,捕获的结果还是第一次捕获的结果
  • 正则属性:lastIndex,表示正则每一次捕获在字符串中开始查找的位置,默认值为0
  • 如果想取消正则的懒惰性,給正则的末尾加修饰符g
    • 原理:增加全局修饰符g后,每一次捕获结束后的lastIndex都会变为最新的索引值。
  1. // lastIndex:捕获开始位置的索引
  2. // 加上修饰符g 之后,每捕获一次,lastIndex就会发生变化,变为下一次捕获开始位置的索引
  3. let str = "fasfasf456sacz153scsz";
  4. let reg = /\d\d\d/;
  5. console.log(reg.lastIndex); // 0
  6. console.log(reg.exec(str)); // [456]
  7. console.log(reg.lastIndex); // 0 由于正则默认只匹配一次(正则匹配的懒惰性)
  8. console.log(reg.exec(str)); // [456]
  9. let reg2 = /\d{3}/g;
  10. console.log(reg2.lastIndex); // 0
  11. console.log(reg2.exec(str)); // [456]
  12. console.log(reg2.lastIndex); // 10 打破了正则匹配的懒惰性
  13. console.log(reg2.exec(str)); // [153]
  14. console.log(reg2.lastIndex); // 17 打破了正则匹配的懒惰性
  15. console.log(reg2.exec(str)); // null 捕获不到,返回值为null

2、封装一个方法:可以把当前字符串中所有符合规则的内容全部捕获,并且以数组形式返回

  • 正则实例的身上有个global属性,判断正则是否包含修饰符g,值为布尔类型
  1. // 封装一个方法:吧当前字符串中的所有符合规则的内容全部捕获,并且以数组形式返回
  2. RegExp.prototype.myExec = function (str) {
  3. // 正则实例身上有一个属性叫做global,如果当前正则有g,那global的值就是true。反之就是false
  4. // 如果用户的正则没有加g,那就捕获一次直接给用户返回出去就好
  5. if (!this.global) {
  6. return this.exec(str);
  7. }
  8. let ary = [];
  9. let estr = this.exec(str);
  10. while (estr) {
  11. ary.push(estr[0]);
  12. estr = this.exec(str);
  13. }
  14. return ary.length ? ary : null;
  15. }
  16. let str = "asc123fas159svas137";
  17. let reg3 = /\d{3}/;
  18. let reg4 = /\d{3}/g;
  19. console.log(reg3.myExec(str));
  20. console.log(reg4.myExec(str));

3、字符串的match()方法

  • match是一个字符串的方法
  • 如果正则匹配不到,返回null
  • 如果当前正则不加g,那方法返回的值跟exec一样
  • 正常情况下返回一个数组,数组里存放的是捕获到的每一项内容;只能拿到每一次大正则捕获的内容,小分组的捕获拿不到。

matchAll();返回值是一个迭代器

String.prototype.matchAll();

  1. // matchAll();方法 返回值是一个迭代器
  2. let Iterator = str.matchAll(reg);
  3. let ary = [];
  4. for (let item of Iterator) {
  5. console.log(item);
  6. ary.push(item[1]);
  7. }
  8. console.log(ary);

封装一个方法:既可以获取大正则捕获的内容,还可以捕获小正则(分组捕获)的内容

  1. // 封装一个方法:既可以获取大正则捕获的内容,还可以捕获小正则(分组捕获)的内容
  2. // 方法一:
  3. String.prototype.myMatch = function (reg) {
  4. if (!reg.global) {
  5. return reg.exec(this);
  6. }
  7. let Iterator = this.matchAll(reg);
  8. let obj = {
  9. big: [],
  10. small: [],
  11. }
  12. for (const item of Iterator) {
  13. obj.big.push(item[0]);
  14. if (item.length>1) {
  15. obj.small.push(item[1]);
  16. }
  17. }
  18. return obj.big.length ? obj : null;
  19. }
  20. let str5 = "ads159fsdg123saf2222dasfasf789";
  21. let reg5 = /\d{3}/g;
  22. str5.myMatch(reg5);
  23. // 方法二:

4、正则的贪婪性

正则捕获的贪婪性:默认情况下,正则的每一次捕获,都是按照最长的匹配结果来捕获的;

在量词元字符后面设置?来取消正则的贪婪性

?的作用

  • 放在普通元字符后面,表示出现0或1次
  • 放在量词元字符后面,表示取消正则捕获时的贪婪性 ```javascript // 正则的贪婪性 let str = ‘2019’; let reg = /\d+/g; console.log(str.match(reg)); // [‘2019’]

//=>在量词元字符后面设置?来取消捕获时候的贪婪性(按照正则匹配的最短结果来获取) reg = /\d+?/g; console.log(str.match(reg)); // [“2”, “0”, “1”, “9”] ```

5、分组捕获