美文网首页
javascript正则表达式 execAll的实现 ----

javascript正则表达式 execAll的实现 ----

作者: 成熟稳重的李先生 | 来源:发表于2019-10-16 01:09 被阅读0次

正则的捕获

实现正则捕获的方法

  • 正则RegExp.prototype上的方法
    • exec
    • test
  • 字符串String.prototype上支持正则表达式处理的方法
    • replace
    • match
    • split
    • ....
//实现捕获的要求是,正则必须匹配这个目标字符串,如果不匹配,捕获的结果是null
let str = "wozai2019,xuexizhengze,20191015"
let reg = /\d+/;  
/*
 *  基于exec实现正则的捕获
 *      1. 捕获到的结果是null或者一个数组
 *            数组第一项: 本次捕获到的内容
 *            (如果有分组(用小括号实现))其余项: 对应小分组本次单独捕获的内容
 *            每一项详解:    index----当前捕获内容在字符串中的起始索引
 *                                      input-----原始字符串
 *       2. 每执行一次exec只能捕获到一个符合正则规则,但是默认情况下,执行多次,获取到的结果永远都是第一个匹配到的, 其余的捕获不到(正则捕获的懒惰性)
*/
console.log(reg.exec(str)); // => ["2019", index: 5, input: "wozai2019,xuexizhengze,20191015", groups: undefined]

/*
 *  lastIndex: 当前正则下一次匹配的起始索引位置
 *  reg.lastIndex  默认是0,从0开始匹配(所以,正则捕获的懒惰性,是因为如果不指定的话,正则的lastIndex总是0)(懒惰性不是只有exec方法,这是正则的特性)
*/
//  lastIndex手动修改是没有用的,全局匹配可以达到这个目的(lastIndex会自动修改)
let str = "wozai2019,xuexizhengze,20191015"
let reg = /\d+/g;  
reg.exec(str);
console.log(reg.lastIndex)  // 9  (从第一个2019后边开始)
reg.exec(str); // 如果将字符串捕获彻底之后,再次捕获的结果是null,但是lastIndex又变成初始值0
//  因此,解决正则的懒惰性 ------  加全局g

/  *
   *  let reg = /^\d+$/;  
   *  console.log(reg.text(str));  // => false
   *  consolle.log(reg.exec(str)); // => null
   * /

如果我们要使用捕获exec,基于以上已知知识,很自然的会写出这种代码:

let reg = /\d+/g;
if(reg.test(str)){   // 我们知道,只有在正则匹配字符串的时候,才能捕获到不为null的结果,这样写好像没问题
  console.log(reg.exec(str))
  console.log(reg.lastIndex)
}

运行

image.png
所以,全局匹配g会改变lastIndex,不管使用的是什么(test,exec)方法,因为懒惰性是正则的特性

但是,如你所见,exec每次只能捕获一个,肯定有这种需求,需要一次全部捕获,接下来,我们实现一个execAll方法

~function(){
  function execAll(str){  //str:要匹配的字符串,默认为空字符串
    // 前提,目标正则必须要加全局“g”,如果不加,则在while处会死循环
    // 因此,第一步要先判断
      if(!this.global) return this.exec(str);
      let ary= [],
         res = this.exec(str);
      while (res) {
        //  把每次捕获到的内容(长度为1的数组)的第一项push到结果数组中
          ary.push(res[0])
         // => 只要捕获的内容不是null,则继续捕获下去
          res = this.exec(str);
      }
      return ary.length === 0 ? null : ary;  //这里为了和字符串的match方法一致
  }
  RegExp.prototype.execAll = execAll;
}()
var str = "234sdfsdf56756df56756rtfdgdfgvbxcv4566";
var reg = /\d+/g;
console.log(reg.execAll(str));   // ["234", "56756", "56756", "4566"]

以上正则的全局捕获方法,在字符串中有原生的实现——match

console.log("234sdfsdf56756df56756rtfdgdfgvbxcv4566".match(/\d+/g))
  // ["234", "56756", "56756", "4566"]

再强调一次,我们实现的execAll是正则的方法;match是字符串的方法

相关文章

网友评论

      本文标题:javascript正则表达式 execAll的实现 ----

      本文链接:https://www.haomeiwen.com/subject/tygemctx.html