把当前字符串中符合正则的字符捕获到 RegExp.prototype:exec 实现正则捕获的方法
var str = '兜兜有糖2017扬帆起航2018'; var reg = /d+/; reg.exec(str); /* * 当正则捕获的时候: * 1、先去验证当前字符串和正则是否匹配,如果不匹配返回的结果是null(没有捕获到任何的内容) * 2、如果匹配,从字符串最左边开始,向右查找到匹配的内容,并且把匹配的内容返回 * * exec捕获到结果的格式: * -> 获取的结果是一个数组 * -> 数组中的第一项是当前本次大正则在字符串中匹配到的结果 * -> index:记录了当前本次捕获到结果的起始索引 * -> input:当前正则操作的原始字符串 * -> 如果当前正则中有分组,获取的数组中,从第二项开始都是每个小分组,本次匹配到的结果(通过exec可以把分组中的内容捕获到) * * 执行一次exec只能把符合正则规则条件中的一个内容捕获都,如果还有其它符合规则的,需要在次执行exec才有可能捕获到 */
正则捕获存在懒惰性
执行一次exec捕获到第一个符合规则的内容,第二次执行exec,捕获到的依然是第一个匹配的内容, 后面匹配的内容不管执行多少次exec都无法捕获到 解决正则捕获的懒惰性: 在正则的末尾加修饰符g(全局匹配)
//=>正则为什么会存在懒惰性? /* * 正则本身有一个属性:lastIndex(下一次正则在字符串中匹配查找的开始索引) * 默认值:0,从字符串第一个字符开始查找匹配的内容 * 默认不管指定多少遍exec方法,正则的lastIndex值都不会变(也就是第二次以后查找的时候还是从第一个字符找, 所以找到的结果永远都是第一个匹配的内容) * 而且当我们手动把 lastIndex 进行修改的时候,不会起到任何的作用 */ //=>为什么加修饰符g就解决了懒惰性? /* * 加了修饰符g,每一次exec结束后,浏览器默认会把lastIndex值进行修改,下一次从上一次结束的位置开始查找, 所以可以得到后面匹配的内容了 */ var reg = /d+/g; var str = '兜兜有糖2017杨帆起航2018'; console.log(reg.lastIndex);//=>0 console.log(reg.exec(str)[0]);//=>'2017' console.log(reg.lastIndex);//=>8 console.log(reg.exec(str)[0]);//=>'2018' console.log(reg.lastIndex);//=>16 console.log(reg.exec(str));//=>null console.log(reg.lastIndex);//=>0 console.log(reg.exec(str)[0]);//=>'2017'
exec有自己的局限性:执行一次exec只能捕获到一个和正则匹配的结果(即使加了修饰符g),如果需要都捕获到,我们需要执行N次exec方法才可以
下面封装的myExecAll方法,目的是执行一次这个方法,可以把当前正则匹配到的全部内容都捕获到
RegExp.prototype.myExecAll = function myExecAll() { var str = arguments[0] || '', result = []; //=>首先判断THIS是否加了全局修饰符G,如果没有加,为了防止下面执行出现死循环,我们只让其执行一次EXEC即可, 把执行一次的结果直接的返回 if (!this.global) { return this.exec(str); } var ary = this.exec(str); while (ary) { result.push(ary[0]); ary = this.exec(str); } return result; }; var reg = /d+/g; console.log(reg.myExecAll('兜兜2017有糖2018我的2019起航2020'));