为什么设置 g
修饰符后 Javascript 子匹配停止工作?
var text = 'test test test test';
var result = text.match(/t(e)(s)t/);
// Result: ["test", "e", "s"]
以上工作正常,result[1]
是 "e"
而 result[2]
是 "s"
.
var result = text.match(/t(e)(s)t/g);
// Result: ["test", "test", "test", "test"]
上面忽略了我的捕获组。以下是唯一有效的解决方案吗?
var result = text.match(/test/g);
for (var i in result) {
console.log(result[i].match(/t(e)(s)t/));
}
/* Result:
["test", "e", "s"]
["test", "e", "s"]
["test", "e", "s"]
["test", "e", "s"]
*/
编辑:
我再次高兴地告诉你,10 年后你现在可以做到这一点(.matchAll 已添加到规范中)
let result = [...text.matchAll(/t(e)(s)t/g)];
最佳答案
如果设置了全局修饰符,使用 String
的 match()
函数将不会返回捕获的组,如您所见。
在这种情况下,您可能希望使用 RegExp
对象并调用其 exec()
函数。 String
的 match()
几乎与 RegExp
的 exec()
函数相同……除了像这样的情况这些。如果设置了全局修饰符,普通的 match()
函数不会返回捕获的组,而 RegExp
的 exec()
函数会. (注意到 here ,以及其他地方。)
要记住的另一个问题是 exec()
不会返回一个大数组中的匹配项——它会一直返回匹配项,直到用完为止,在这种情况下它会返回 null
.
因此,例如,您可以执行以下操作:
var pattern = /t(e)(s)t/g; // Alternatively, "new RegExp('t(e)(s)t', 'g');"
var match;
while (match = pattern.exec(text)) {
// Do something with the match (["test", "e", "s"]) here...
}
另外需要注意的是 RegExp.prototype.exec()
和 RegExp.prototype.test()
对提供的字符串执行正则表达式并返回第一个结果。每个顺序调用都将遍历结果集,根据字符串中的当前位置更新 RegExp.prototype.lastIndex
。
举个例子: //请记住示例和模式中有 4 个匹配项。 lastIndex 从 0 开始
pattern.test(text); // pattern.lastIndex = 4
pattern.test(text); // pattern.lastIndex = 9
pattern.exec(text); // pattern.lastIndex = 14
pattern.exec(text); // pattern.lastIndex = 19
// if we were to call pattern.exec(text) again it would return null and reset the pattern.lastIndex to 0
while (var match = pattern.exec(text)) {
// never gets run because we already traversed the string
console.log(match);
}
pattern.test(text); // pattern.lastIndex = 4
pattern.test(text); // pattern.lastIndex = 9
// however we can reset the lastIndex and it will give us the ability to traverse the string from the start again or any specific position in the string
pattern.lastIndex = 0;
while (var match = pattern.exec(text)) {
// outputs all matches
console.log(match);
}
您可以找到有关如何使用 RegExp
对象的信息 on the MDN (具体来说,这是 the exec()
function 的文档)。
关于JavaScript 正则表达式和子匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/844001/