match Vs exec in JavaScript

match Vs exec in JavaScript

本文关键字:JavaScript in exec Vs match      更新时间:2023-09-26

我需要对JavaScript中的match Vs exec进行一些澄清;这里有人说

"带有全局正则表达式的exec

应该在循环中使用",但首先,正如您在我的例子中看到的那样,情况并非如此;在我的示例中,带有全局正则表达式的exec返回数组中的所有匹配项!其次,他们说对于 String.match,它返回所有匹配项,无需循环!但同样,在我的示例中没有发生这种情况,它只是返回输入字符串?我是否误解/做错了什么?

var myString = "[22].[44].[33].";
var myRegexp = /.*'[('d*)*'].*'[('d*)*'].*'[('d*)*'].*/g;
var execResult = myRegexp.exec(myString);
console.log(execResult.length);
console.log(execResult[1]);// returns 22 and execResult has all of my matches from index 1 to the length of array

var matchResult = myString.match(myRegexp);
console.log(matchResult.length);
console.log(matchResult);// returns just myString which is "[22].[44].[33]."! Why is that?
  1. string.match 查找第一个匹配项,并在不使用全局标志时返回实际匹配项、找到文本的索引和实际输入。

  2. string.match 只返回使用全局标志时的所有匹配项。

var myString = "[22].[44].[33].";
    
console.log(myString.match(/'d+/)); 
// [ '22', index: 1, input: '[22].[44].[33].' ]
console.log(myString.match(/'d+/g));
// [ '22', '44', '33' ]

string.matchregex.exec 之间的主要区别在于,regex对象将通过regex.exec调用更新当前匹配项。例如

var myString = "[22].[44].[33].", myRegexp = /'d+/g, result;
while (result = myRegexp.exec(myString)) {
    console.log(result, myRegexp.lastIndex);
}

会回来

[ '22', index: 1, input: '[22].[44].[33].' ] 3
[ '44', index: 6, input: '[22].[44].[33].' ] 8
[ '33', index: 11, input: '[22].[44].[33].' ] 13

如您所见,只要找到匹配项,lastIndex 属性就会更新。因此,当您使用exec时,请记住两件事,否则您将遇到无限循环。

  1. 如果您不使用g选项,那么您将始终获得第一个匹配项(如果有的话),否则null .因此,以下内容将陷入无限循环。

    var myString = "[22].[44].[33].", myRegexp = /'d+/, result;
    while (result = myRegexp.exec(myString)) {
        console.log(result, myRegexp.lastIndex);
    }
    
  2. 不要忘记在后续调用中使用相同的正则表达式对象。因为,正则表达式对象每次都会更新,如果你传递新对象,程序将再次进入无限循环。

    var myString = "[22].[44].[33].", result;
    while (result = /'d+/g.exec(myString)) {
        console.log(result);
    }
    

String.prototype.match()RegExp.prototype.exec() 在查找多个匹配项并在数组中返回它们方面相似。然而,exec 方法返回一组更详细的信息。例如,与匹配不同,它还可以找到捕获组的多次出现。因此,如果您有捕获组,exec 是必不可少的。在使用 exec 时要记住的一件事,您不应该从文字正则表达式中调用 if。首先将正则表达式分配给变量,然后使用它来调用 exec 方法。另一件事是,虽然匹配会一次在项目数组中带来多个匹配项,但使用 exec,您必须迭代以捕获每个匹配项。

调用匹配相当简单。由于它是一个字符串原型方法,您只需将其链接到字符串并提供正则表达式作为匹配方法的参数,例如;"test".match(/es/) 正则表达式的文字表示可以毫无问题地使用。

调用 exec 更为复杂。正如我之前提到的,最好将正则表达式分配给以前的某些东西。好的,让我们看一个例子

var text = '["job name 1","nat 1"],["job name 2","nat 2"],["job name 3","nat 3"]',
     reg = /([^"]+)","([^"]+)/g,
      tm = [],
      te = [];
tm = text.match(reg); // tm has result of match
while(te[te.length]=reg.exec(text)); // te has result of exec + an extra null item at the end
te.length--; // te normalized.
document.write("<pre>" + JSON.stringify(tm,null,2) + "</pre>'n");
document.write("<pre>" + JSON.stringify(te,null,2) + "</pre>'n");

如您所见,exec 的结果还包括捕获组。我选择填充数组的方式有些非正统te但我讨厌在 while 循环的条件部分使用临时数组。在我看来,这要整洁得多。唯一的问题是,用于停止 while 循环的最后一个 null入到数组te末尾。因此,以下te.length--说明。

编辑:现在还有现代浏览器中可用的String.prototype.matchAll()功能,它主要减轻了使用exec的负担。你可以看看我的另一个答案,看看它的实际效果。