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

正则的特性

贪婪性

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

懒惰性

懒惰性则是正则在成功捕获一次后不管后边的字符串有没有符合条件的都不再捕获。
如果想捕获目标中所有符合条件的字符串的话,我们可以用标识符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"]

   

结果:

关于正则表达式 中分组捕获和贪婪性、懒惰性的探究_第1张图片

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

 

关于正则表达式 中分组捕获和贪婪性、懒惰性的探究_第2张图片

 

关于正则表达式 中分组捕获和贪婪性、懒惰性的探究_第3张图片

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}

 

 

 

你可能感兴趣的:(Javascript,javascript)