js中的正则表达式入门(大量实例代码)(3)

每次调用exec方法时,捕获到的字符串都不相同
lastIndex :这个属性记录的就是下一次捕获从哪个索引开始。
当未开始捕获时,这个值为0。
如果当前次捕获结果为null。那么lastIndex的值会被修改为0.下次从头开始捕获。
而且这个lastIndex属性还支持人为赋值。

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

var str = '2017-01-05'; var reg = /-(\d+)/g // ["-01", "01", index: 4, input: "2017-01-05"] "-01" : 正则捕获到的内容 "01" : 捕获到的字符串中的小分组中的内容

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"]

上边两个方法console的结果有什么不同呢?二个字符串是一样滴。
当我们进行全局匹配时,二者的不同就会显现出来了.

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的第二个参数也可以是一个函数 str.replace(reg,fn); var str = '2017-01-06'; 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}

零宽断言

用于查找在某些内容(但并不包括这些内容)之前或之后的东西,如\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。

在使用正则表达式时,捕获的内容前后必须是特定的内容,而我们又不想捕获这些特定内容的时候,零宽断言就可以派上用场了。

零宽度正预测先行断言 (?=exp)

零宽度负预测先行断言 (?!exp)

零宽度正回顾后发断言 (?<=exp)

零宽度负回顾后发断言 (?<!exp)

这四胞胎看着名字好长,给人一种好复杂好难的感觉,我们还是挨个来看看它们究竟是干什么的吧。

(?=exp) 这个简单理解就是说字符出现的位置的右边必须匹配到exp这个表达式。

var str = "i'm singing and dancing"; var reg = /\b(\w+(?=ing\b))/g var res = str.match(reg); console.log(res) // ["sing", "danc"]

注意一点,这里说到的是位置,不是字符。

var str = 'abc'; var reg = /a(?=b)c/; console.log(res.test(str)); // false // 这个看起来似乎是正确的,实际上结果是false

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwyfjw.html