关于正则表达式 中分组捕获和贪婪性、懒惰性的探究

正则的特性

贪婪性

所谓的贪婪性就是正则在捕获时,每一次会尽可能多的去捕获符合条件的内容。
如果我们想尽可能的少的去捕获符合条件的字符串的话,可以在量词元字符后加?

懒惰性

懒惰性则是正则在成功捕获一次后不管后边的字符串有没有符合条件的都不再捕获。
如果想捕获目标中所有符合条件的字符串的话,我们可以用标识符g来标明是全局捕获

var str = '123aaa456';

var reg = /\d+/;  //只捕获一次,一次尽可能多的捕获

var res = str.match(reg)

console.log(res)// ["123"]

reg = /\d+?/g; //解决贪婪性、懒惰性

res = str.match(reg)

console.log(res)// ["1", "2", "3", "4", "5", "6"]

   <script>
        var str = '123aaa456';
        reg = /\d+?/g; //解决贪婪性、懒惰性
        res = str.match(reg);
        alert(res);
    </script>

结果:

exec的捕获还受分组()的影响

 <script>
        var str = '2017-01-05';
        var reg = /-\d+/g;
        res=reg.exec(str);
        alert(res);
    </script>

 <script>
        var str = '2017-01-05';
        var reg = /-(\d+)/g;
        res=reg.exec(str);
        alert(res);
    </script>

match和replace详解

  • str.match(reg) 如果匹配成功,就返回匹配成功的数组,如果匹配不成功,就返回null

//match和exec的用法差不多

var str = 'abc123cba456aaa789';

var reg = /\d+/;

console.log(reg.exec(str));

//["123", index: 3, input: "abc123cba456aaa789"]

console.log(str.match(reg));

//["123", index: 3, input: "abc123cba456aaa789"]

在此看来结果没什么不同,但是 当我们进行全局匹配时,二者的不同就显示出来了。

var str = 'abc123cba456aaa789';

var reg = /\d+/g;

console.log(reg.exec(str));

// ["123", index: 3, input: "abc123cba456aaa789"]

console.log(str.match(reg));

// ["123", "456", "789"]

当全局匹配时,match方法会一次性把符合匹配条件的字符串全部捕获到数组中,
如果想用exec来达到同样的效果需要执行多次exec方法。

我们可以尝试着用exec来简单模拟下match方法的实现。

 String.prototype.myMatch = function (reg) {

    var arr = [];

    var res = reg.exec(this);

    if (reg.global) {

        while (res) {

            arr.push(res[0]);

            res = reg.exec(this)

        }

    }else{

        arr.push(res[0]);

    }

    return arr;

}

var str = 'abc123cba456aaa789';var reg = /\d+/;console.log(str.myMatch(reg))// ["123"]

var str = 'abc123cba456aaa789';var reg = /\d+/g;console.log(str.myMatch(reg))// ["123", "456", "789"]

重点:此外,match和exec都可以受到  分组()的影响,不过match只在没有标识符g的情况下才显示小分组的内容,如果有全局g,则match会一次性全部捕获放到数组中

var str = 'abc';

var reg = /(a)(b)(c)/;

console.log( str.match(reg) );

// ["abc", "a", "b", "c", index: 0, input: "abc"]

console.log( reg.exec(str) );

// ["abc", "a", "b", "c", index: 0, input: "abc"]

当有全局g的情况下

var str = 'abc';

var reg = /(a)(b)(c)/g;

console.log( str.match(reg) );

// ["abc"]

console.log( reg.exec(str) );

// ["abc", "a", "b", "c", index: 0, input: "abc"]

str.replace() 这个方法大家肯定不陌生,现在我们要说的就是和这个方法和正则相关的东西了。

正则去匹配字符串,匹配成功的字符去替换成新的字符串

写法:str.replace(reg,newStr);

var str = 'a111bc222de';

var res = str.replace(/\d/g,'Q');

console.log(res)// "aQQQbcQQQde";

replace的第二个参数也可以是一个函数

var str = '2017-01-06';

var reg=/-\d+/g;

str = str.replace(/-\d+/g,function(){

    console.log(arguments)

});

控制台打印结果:

["-01", 4, "2017-01-06"]

["-06", 7, "2017-01-06"]"2017undefinedundefined"

从打印结果我们发现每一次输出的值似乎跟exec捕获时很相似,既然与exec似乎很相似,那么似乎也可以打印出小分组中的内容喽

var str = '2017-01-06';

str = str.replace(/-(\d+)/g,function(){

    console.log(arguments)

})

["-01", "01", 4, "2017-01-06"]

["-06", "06", 7, "2017-01-06"]"2017undefinedundefined"

从结果看来我们的猜测没问题。

 

此外,我们需要注意的是,如果我们需要替换replace中正则找到的字符串,函数中需要一个返回值去替换正则捕获的内容。

通过replace方法获取url中的参数的方法

(function(pro){

    function queryString(){

        var obj = {},

            reg = /([^?&#+]+)=([^?&#+]+)/g;

        this.replace(reg,function($0,$1,$2){

            obj[$1] = $2;

        })

        return obj;

    }

    pro.queryString = queryString;

}(String.prototype));

// 例如 url为 https://www.baidu.com?a=1&b=2// window.location.href.queryString();// {a:1,b:2}

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值