深入javascript中的exec与match方法
深入javascript中的exec与match方法
经典面试题,如果知晓一下题目的答案,那就没有必要往下看了。
var someText="web2.0 2.0"; var pattern=/(\w+)(\d)\.(\d)/g; var outCome_exec=(someText); var outCome_matc=(pattern); What is outCome_exec[1] and outCome_matc[1]? Choice A: true Choice B: false Choice C: null Choice D: Web Choice E: Web2.0 Choice F: undefined Choice G: net2.0 思考1分钟ing........ 在使用match方法时,如果不指定g属性,则与RegExp对象的exec方法可以等价,而不是只有一个元素的数组。 举例: var str= "ahi" ; var exp=/a(hi)/; var arr1 = (str); var arr2 = (exp); alert(arr1);//结果:arr1.length==2;arr1[0]==ahi;arr1[1]==hi; alert(arr2);//结果:arr2.length==2;arr2[0]==ahi;arr1[1]==hi;结果同上 -2)同时,在js帮助文档中,在执行exec方法时,如果有属性g,将该对象的匹配的开始位置设置到紧接这匹配子串的字符位置,当第二次调用exec时,将从 lastIndex所指示的字符位置开始检索。利用这个特点可以反复调用exec遍历所有匹配,此时等价于match具有g属性的情况(其实就是将匹配的结果放入Matches 集合中去了)。 举例如下: a)有属性g的情况时,更新了index和lastIndex,对下次检索起到作用: function RegExpTest() { var src = "The rain in Spain falls mainly in the plain."; var re = /(\w+)/g; // 创建正则表达式模式。 var arr; while ((arr = (src)) != null){ document.write(arr.index + "-" + RegExp.lastIndex + "\t" + arr[0]);//此处RegExp.lastIndex和arr.lastIndex均有同样的属性,可以互换。在此注意IE6和7的lastIndex重设置0的bug } }; RegExpTest(); //以上例子可以遍历所匹配的内容。并可得到每个小匹配的index和lastIndex; b)如果以上例子没有g的情况,则以上例子,exec方法没有更新RegExp 对象的全局属性(index、lastIndex等),以上例子会陷入死循环,index和lastIndex一直为0和 可见属性g在exec过程中可以改变index和lastIndex等的值,以便下一次检索的位置,match方法无此能力。 4.关于index和lastIndex等属性(帮助中还有leftContext、rightContext、lastMatch、lastParen(最后一个括号),但是这些属性均以index和lastindex为基础)。 4-1)只读属性。 如下例子: var src = "The rain in Spain falls mainly in the plain."; var re = /(\w+)/g; // 创建正则表达式模式。 var arr; arr = (src); RegExp.lastIndex = 0; RegExp.index = 0; arr.lastIndex = 0; arr.index = 0; document.write(arr.index + "-" + arr.lastIndex + "\t" + arr[0]+"**********"+RegExp.index + "-" + RegExp.lastIndex + "\t" + arr[0]); //结果为0-0 The**********0- The。 究其原因也就是RegExp的属性是只读的,即使js语言的灵活性,可以修任何属性或添加任何属性,均不报语法错误。但是依旧无法RegExp的属性更改,但是arrary对象则是可以更改,但是每次执行一次exec,就会将RegExp.index等属性重新赋值给返回的Arrary对象。 例如: var src = "The rain in Spain falls mainly in the plain."; var re = /(\w+)/g; // 创建正则表达式模式。 var arr; arr = (src); RegExp.lastIndex = 0; RegExp.index = 0; arr.lastIndex = 0; arr.index = 0; document.write(arr.index + "-" + arr.lastIndex + "\t" + arr[0]+"**********"+RegExp.index + "-" + RegExp.lastIndex + "\t" + arr[0]); //执行第二次arr的index属性会被更新,其实是RegExp对象实例在执行exec方法时,更新全局的RegExp.index和arr的index等,在后边会介绍 arr = (src); document.write("<br/>"+arr.index + "-" + arr.lastIndex + "\t" + arr[0]+"**********"+RegExp.index + "-" + RegExp.lastIndex + "\t" + arr[0]); //0-0 The**********0- The //4-8 rain**********4-8 rain 4-2)不同的RegExp实例对象交叉执行exec时,index、lastIndex等属性互不影响。每次执行exec或者执行String的match方法时,都会给RexExp.index等赋予新值。(这个其实是必须的,只是我在这脑袋一犯浑,给理解错了,主要是因为“RegExp.lastIndex = 0;”可以被赋值,但是取值时,结果又没有改变,让我脑袋混乱了。) 开始我以为如果两个RegExp对象在交叉执行exec时,可能index等会清零。因为我认为index属性是保存在RegExp的全局静态属性上的。现在发现是保存在具体的RegExp实例上,每次执行exec或者执行String的match方法时,都会给RexExp.index等赋予新值。 呵呵,这可能是习惯了c和java中类和类实例的想法的人常犯的错误,认为RegExp是个类,RegExp.index是一个类的static属性。这样认为没错,但是他的值是是会在执行exec和String的match方法时,被正则对象更新。 举例如下: var src = "The rain in Spain falls mainly in the plain."; var re1 = /(\w+)/; // 创建正则表达式模式。 var re2 = /(\w+)/g; // 创建正则表达式模式。 var arr; arr = (src); document.write("R1第一次执行exec:"+RegExp.index + "-" + RegExp.lastIndex + "\t" + arr[0]); arr = (src); document.write("<br/>R2第一次执行exec:"+RegExp.index + "-" + RegExp.lastIndex + "\t" + arr[0]); arr = (src); document.write("<br/>R1第二次执行exec:"+RegExp.index + "-" + RegExp.lastIndex + "\t" + arr[0]); arr = (src); document.write("<br/>R2第二次执行exec:"+RegExp.index + "-" + RegExp.lastIndex + "\t" + arr[0]); 输出的结果如下: R1第一次执行exec:0- The R2第一次执行exec:0- The R1第二次执行exec:0- The R2第二次执行exec:4-8 rain 4-)String对象的match方法,无法像exec方法那样获取中间查的对象的index和lastIndex,也就是说是一次性的。即无法得到下一次检索的位置,match方法在设置g属性时,只能获取最后一个检索和index和lastIndex;match在没有设置g属性时,仅仅获得第一个匹配的index和lastIndex。 举例如下: a) var src = "The rain in Spain falls mainly in the plain."; var re = /\w+/g; //有g属性。 var i = 0; while (i++<10){ arr = (re); document.write(RegExp.index + "-" + RegExp.lastIndex + "\t" + arr + "<br/>"); } //结果如下: 8-4 The,rain,in,Spain,falls,mainly,in,the,plain 8-4 The,rain,in,Spain,falls,mainly,in,the,plain 8-4 The,rain,in,Spain,falls,mainly,in,the,plain 8-4 The,rain,in,Spain,falls,mainly,in,the,plain 8-4 The,rain,in,Spain,falls,mainly,in,the,plain 8-4 The,rain,in,Spain,falls,mainly,in,the,plain 8-4 The,rain,in,Spain,falls,mainly,in,the,plain 8-4 The,rain,in,Spain,falls,mainly,in,the,plain 8-4 The,rain,in,Spain,falls,mainly,in,the,plain 8-4 The,rain,in,Spain,falls,mainly,in,the,plain b) var src = "The rain in Spain falls mainly in the plain."; var re = /\w+/; // 无g属性。 var i = 0; while (i++<10){ arr = (re); document.write(RegExp.index + "-" + RegExp.lastIndex + "\t" + arr + "<br/>"); } //结果如下: 0- The 0- The 0- The 0- The 0- The 0- The 0- The 0- The 0- The 0- The c) var src = "The rain in Spain falls mainly in the plain."; var re = /\w+/g; var i = 0; arr = (re); while (arr[i]!=null){ document.write(RegExp.index + "-" + RegExp.lastIndex + "\t" + arr[i] + "<br/>"); i++; } //结果如下: 8-4 The 8-4 rain 8-4 in 8-4 Spain 8-4 falls 8-4 mainly 8-4 in 8-4 the 8-4 plain 5.最后结论(如有不对,请指正): 1)exec是RegExp对象方法,match是String对象方法; 2)如果没有到结果,则二者都返回null; )只有在正则表达式必须指定全局g属性时,match才能返回所有匹配,否则match与exec方法结果无差异,是等价的; 4)exec永远返回与第一个匹配相关的信息,其返回数组第一个值是第一个匹配的字串,剩下的是所有分组的反向引用(即子括号的匹配内容); 5)exec在设置g属性后,虽然匹配结果不受g的影响,返回结果仍然是一个数组(第一个值是第一个匹配到的字符串,以后的为分组匹配内容),但是会改变index和lastIndex等的值,将该对象的匹配的开始位置设置到紧接这匹配子串的字符位置,当第二次调用exec时,将从lastIndex所指示的字符位置开始检索。同样match方法在设置了g属性后,也会改变index和lastIndex的值,但是是一次性的。无法像exec那样能逐过程累积(即将结果放入Matches 集合中去了),因此无法累积获取下一次检索的位置。 PS: 最开始那个问题的答案为D和G。你想明白了么? 以上测试均在ie和firefox中测试过,结果一致。 以上测试的前提是javascript支持RegExp对象。早期浏览器的javascript引擎未必支持正则对象或者未必支持正则表达式对象的某些属性。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2022-0-09,如有侵权请联系 cloudcommunity@tencent 删除javascript正则表达式execmatch对象#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 19 条评论) |
本站网友 vmware8 | 2分钟前 发表 |
the | |
本站网友 泰安宾馆 | 8分钟前 发表 |
将从lastIndex所指示的字符位置开始检索 | |
本站网友 欧科电磁炉 | 24分钟前 发表 |
因为我认为index属性是保存在RegExp的全局静态属性上的 | |
本站网友 空姐的要求 | 16分钟前 发表 |
呵呵 | |
本站网友 卫生巾什么牌子好 | 10分钟前 发表 |
0- The R2第一次执行exec | |
本站网友 中国黄山 | 5分钟前 发表 |
无法像exec那样能逐过程累积(即将结果放入Matches 集合中去了) | |
本站网友 相册密码 | 23分钟前 发表 |
举例如下: var src = "The rain in Spain falls mainly in the plain."; var re1 = /(\w+)/; // 创建正则表达式模式 | |
本站网友 南京小学辅导 | 10分钟前 发表 |
每次执行exec或者执行String的match方法时 | |
本站网友 浦江镇规划 | 17分钟前 发表 |
the | |
本站网友 痔疮的偏方 | 0秒前 发表 |
net2.0 思考1分钟ing........ 在使用match方法时 | |
本站网友 嘉柏俪香薰护肤品 | 18分钟前 发表 |
in | |
本站网友 全球使命国际版下载 | 19分钟前 发表 |
the | |
本站网友 苍蝇的幼虫叫什么 | 15分钟前 发表 |
只是我在这脑袋一犯浑 | |
本站网友 指南针炒股软件下载 | 29分钟前 发表 |
plain 8-4 The | |
本站网友 人人网小黄鸡 | 27分钟前 发表 |
rain | |
本站网友 降准 | 30分钟前 发表 |
match才能返回所有匹配 | |
本站网友 三甲港 | 26分钟前 发表 |
var someText="web2.0 2.0"; var pattern=/(\w+)(\d)\.(\d)/g; var outCome_exec=(someText); var outCome_matc=(pattern); What is outCome_exec[1] and outCome_matc[1]? Choice A | |
本站网友 灵丘58 | 14分钟前 发表 |
mainly |