在 JavaScript 中匹配 Vs exec
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27753246/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
match Vs exec in JavaScript
提问by thefourtheye
I need some clarification for match Vs exec in JavaScript; heresome one says that
我需要对 JavaScript 中的 match Vs exec 进行一些说明;这里有人说
"exec with a global regular expression is meant to be used in a loop"but first of all as you see in my example this is not the case; in my example exec with global regular expression is returning all of the matches in an array! Secondly they say that for String.match it returns all of the matches with no need of looping through! But again that's not happening in my example and it is just returning the input string? Have I misunderstood/done something wrong?
“带有全局正则表达式的 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?
回答by thefourtheye
string.matchfinds the first match and returns it with the actual match, the index at which the text was found and the actual input, when the global flag is not used.string.matchjust returns all the matches, when the global flag is used.
string.match当不使用全局标志时,找到第一个匹配项并返回它与实际匹配项、找到文本的索引和实际输入。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' ]
The main difference between string.matchand regex.execis, the regexobject will be updated of the current match with regex.execcall.For example,
string.match和之间的主要区别regex.exec是,regex对象将更新当前与regex.exec调用匹配的对象。例如,
var myString = "[22].[44].[33].", myRegexp = /\d+/g, result;
while (result = myRegexp.exec(myString)) {
console.log(result, myRegexp.lastIndex);
}
will return
将返回
[ '22', index: 1, input: '[22].[44].[33].' ] 3
[ '44', index: 6, input: '[22].[44].[33].' ] 8
[ '33', index: 11, input: '[22].[44].[33].' ] 13
As you can see, the lastIndexproperty is updated whenever a match is found. So, keep two things in mind when you use exec, or you will run into an infinite loop.
如您所见,lastIndex只要找到匹配项,就会更新该属性。因此,在使用 时请记住两件事exec,否则您将陷入无限循环。
If you don't use
goption, then you will always get the first match, if there is one, otherwisenull. So, the following will run into an infinite loop.var myString = "[22].[44].[33].", myRegexp = /\d+/, result; while (result = myRegexp.exec(myString)) { console.log(result, myRegexp.lastIndex); }Don't forget to use the same regular expression object with subsequent calls. Because, the regex object is updated every time, and if you pass new object, again the program will run into an infinite loop.
var myString = "[22].[44].[33].", result; while (result = /\d+/g.exec(myString)) { console.log(result); }
如果您不使用
goption,那么您将始终获得第一个匹配项,如果有,则为null。因此,以下内容将陷入无限循环。var myString = "[22].[44].[33].", myRegexp = /\d+/, result; while (result = myRegexp.exec(myString)) { console.log(result, myRegexp.lastIndex); }不要忘记在后续调用中使用相同的正则表达式对象。因为,正则表达式对象每次都会更新,如果传入新对象,程序又会陷入无限循环。
var myString = "[22].[44].[33].", result; while (result = /\d+/g.exec(myString)) { console.log(result); }
回答by Redu
String.prototype.match()and RegExp.prototype.exec()are similar in both finding multiple occurrences and returning them in an array. Yet exec method returns an array of more detailed information. For instance unlike match it can find multiple occurrences of the capture groups as well. So if you have capture groups, exec is essential. One thing to keep in mind when working with exec you shouldn't invoke if from a literal regexp. Assign your regex to a variable first and use it to call your exec method from. One other thing is, while match would bring multiple occurrences in an array of items at one go, with exec you have to iterate for each occurrence to be captured.
String.prototype.match()并且RegExp.prototype.exec()在查找多次出现并将它们返回到数组中是相似的。然而 exec 方法返回一个包含更详细信息的数组。例如,与 match 不同,它也可以找到多次出现的捕获组。所以如果你有捕获组, exec 是必不可少的。使用 exec 时要记住的一件事是,您不应该从文字正则表达式中调用 if 。首先将您的正则表达式分配给一个变量,然后使用它来调用您的 exec 方法。另一件事是,虽然 match 会一次在一组项目中多次出现,但使用 exec 您必须迭代每个要捕获的出现。
Invoking match is fairly simple. Since it is a string prototype method you just chain it to a string and provide a regexp as an argument to the match method like; "test".match(/es/) A literal representation of a regex can be used with no problem.
调用 match 相当简单。由于它是一个字符串原型方法,您只需将它链接到一个字符串并提供一个正则表达式作为 match 方法的参数,例如;"test".match(/es/) 可以毫无问题地使用正则表达式的文字表示。
Invoking exec is more complicated. As i mentioned previously it's best to have the regex assigned to something previously. Ok lets see an example
调用 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");
As you see exec's result also includes the capture groups. The way i choose to populate tearray is somewhat unorthodox but i hate to use a temp array just in the conditional part of while loop. This looks to me much more neat. The only thing is, the final null to stop the while loop gets inserted to the end of tearray. Hence the following te.length--instruction.
如您所见,exec 的结果还包括捕获组。我选择填充te数组的方式有点不正统,但我讨厌在 while 循环的条件部分使用临时数组。这在我看来更整洁。唯一的事情是,停止 while 循环的最后一个 null 被插入到te数组的末尾。因此有以下te.length--说明。
Edit: Now there is also the String.prototype.matchAll()functionality available in modern browsers which mostly lifts the burden of using exec over our shoulders. You may look another answer of mine to see that in action.
编辑:现在现代浏览器中还提供了String.prototype.matchAll()功能,它主要减轻了我们肩上使用 exec 的负担。您可以查看我的另一个答案以了解其实际效果。

