您的位置:首页 > Web前端 > JavaScript

javascript中match方法和exec()方法详解与深度区别(非原创)

2017-10-04 11:43 441 查看

match和exec的比较

1.match

match方法属于String正则表达方法. 
语法: str.match(regexp或者string)
str:要进行匹配的字符串. regexp:一个正则表达式(或者由RegExp()构造成的正则表达式)
match的用法主要区分就是,正则表达式是否有全局标示g.
(1)如果有g全局标志,那么返回的数组保存的是,所有匹配的内容,不包括子匹配。

(2))如果没有g全局标志,那么返回的数组arr.arr[0]保存的是完整的匹配.arr[1]保存的是第一个括号里捕获的字串,依此类推arr
保存的是第n个括号捕获的内容.也就是当包含有全局的标志时则返回的结果第一个是正确匹配的结果,后面依次是子匹配的结果。

看一下在控制台输出的结果:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>match全局方法</title>
</head>
<body>
<p id="demo">单击显示查找的位置</p>
<button onclick="myFunction()">点我</button>
<button onclick='myFunctions()'>点击</button>
<script>
function myFunction(){
var str="thiS is my house"
var n=str.match(/is/i);
console.log(n);
}
function myFunctions(){
var str="thiS is my house"
document.getElementById('demo').innerHTML=str.search('is')
}
</script>
</body>
</html>




<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>match全局方法</title>
</head>
<body>
<p id="demo">单击显示查找的位置</p>
<button onclick="myFunction()">点我</button>
<button onclick='myFunctions()'>点击</button>
<script>
function myFunction(){
var str="thiS is my house"
var n=str.match(/is/ig);
console.log(n);
}
function myFunctions(){
var str="thiS is my house"
document.getElementById('demo').innerHTML=str.search('is')
}
</script>
</body>
</html>





这就是match返回的值。



注意:在非全局匹配的时候,数组第一项是整段字符串的匹配,第二项至以后都是捕获匹配。如果match函数加了/g标志位,返回的数组里只包含整段字符串的匹配。

2.exec

与match方法不同exec属于正则表达式对象的方法.

语法:var result1 = regexp.exec(str);

regexp:正则表达式(可以直接定义也可以利用RegExp的方式定义) str:要匹配的字串

exec与match的关联就是:exec(g有没有都无影响)就等价于不含有g全局标志的match.即返回数组arr[0]为匹配的完整串。arr[1...n]为括号里捕获的字符串(当含有子匹配时).

(1)、如果exec执行的正则表达式没有子表达式(子表达式即小括号内的内容,如/abc(\s*)/中的(\s*)),且如果有匹配,就返回第一个匹配的字符串内容,此时的类数组中的第一个元素为匹配的内容,(类数组中还包含有index:匹配字符串在原始字符串中的位置,input:输入的字符串)如果没有匹配返回null;

另外:

var reg = new RegExp("abc") ;
var str = "3abc4,5abc6";
alert(reg.exec(str));
alert(str.match(reg));


    执行如上代码,你会发现两者内容均为一样:abc,此时exec 中没有子表达式同时两者均为非全局的匹配

********子表达式捕获的内容就是指的第一个完全匹配的字符串中在表达式匹配的部分:

var a=/^([^.]*)(?:\.(.+)|)$/;

var str="click.41646ass.sss";

var b=a.exec(str); console.log(b)

   输出["click.41646ass.sss", "click", "41646ass.sss"],正则表达式中共有三个括号但是第二个大括号采用?:的方法取消了捕获,也就是不输出匹配字符串中该子表达式匹配的部分,click对应([^.]*),41646ass.sss对应(.+),所以当为a=/^([^.]*)(\.(.+)|)$/时输出的结果为:["click.41646ass.sss",
"click",".41646ass.sss" ,"41646ass.sss"],.41646ass.sss对应于(?:\.(.+)|)

 

(2)、当exec和match中具有相同的子表达式且为非全局匹配时两者的输出也是相同的,同时输出的数组中含有的多个元素。

var str="visit W3cschool  a W3cschool bull";
var reg=new RegExp("W3c(school)");
var b=reg.exec(str);
alert(b)
alert(str.match(reg))
console.log(b);
console.log(str.match(/W3c(school)/));


执行上诉代码的结果都为W3cschool,school



 

(3)、当为全局匹配时

 var str="visit W3cschool  a W3cschool bull";

var reg=new RegExp("W3cschool",'g');

var b=reg.exec(str);

console.log(b);

console.log(str.match(/W3cschool/g));

exec中没有子表达式其输出为W3cschool,其输出只一个,match全局匹配时其输出元素中将包含所有的匹配项,其输出为W3cshcool,W3cschool



总结为:

(1)Match在非全局匹配时其他几种情况下(有无子匹配的情况下)的返回结果和exec是相同的,在全局匹配时其将返回包含所有匹配项的数组(其中不包含子匹配)。

(2)exec中不管是不是全局的匹配,只要没有子表达式,其返回的都只有一个元素.

如果是全局匹配,可以利用其非全局匹配没有的的lastIndex属性进行下一个匹配,匹配成功后lastIndex的值将会变为上次匹配的字符的最后一个位置的索引。在设置g属性后,虽然匹配结果不受g的影响,返回结果仍然是一个数组(第一个值是第一个匹配到的字符串,以后的为分组匹配内容),但是会改变index和
lastIndex等的值,将该对象的匹配的开始位置设置到紧接这匹配子串的字符位置,当第二次调用exec时,将从lastIndex所指示的字符位置开始检索。同样match方法在设置了g属性后,也会改变index和lastIndex的值,但是是一次性的。无法像exec那样能逐过程累积,因此无法累积获取下一次检索的位置。(match的全局匹配返回的值本身没有lastIndex和index属性,这里只是引用其含义来说明问题)

  
var patt = new RegExp('ab', 'g');
var str = 'abcdef12ab34cd56ef';
var ret;
while((ret = patt.exec(str))!=null) {
document.write(ret+"</br>");
document.write("ret.input="+ret.input+"</br>");
document.write("ret.index="+ret.index+"</br>");
document.write("RegExp.lastIndex ="+patt.lastIndex +"</br>");
}


注意:当没有全局的变量g时,由于index和lastindex的值不会变化(除非手动修改),则会导致每次的陪匹配都是从字符串的头开始的,所以只要字符串中有匹配,就会导致死循环。当时设置g后,会自动改变前面的两个属性,会依次向后匹配直到没有匹配项退出循环(调用lastIndex属性要用正则表达式的对象)

输出结果:

ab

ret.input=abcdef12ab34cd56ef

ret.index=0

RegExp.lastIndex =2

ab

ret.input=abcdef12ab34cd56ef

ret.index=8

RegExp.lastIndex =10

(3)exec返回的是类数组,match返回的也是类数组

原文来自:http://blog.csdn.net/heshan1992/article/details/77361194


我在原文的基础上略作了修改。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息