正则捕获

把当前字符串中符合正则的字符捕获到 
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'));