为什么在设置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)];
发布于 2019-05-15 23:44:24
令我惊讶的是,我是第一个用我10年前寻找的答案回答这个问题的人(答案当时还不存在)。我也希望实际的规范作者会在我之前回答这个问题;)。
.matchAll已经添加到一些浏览器中。
在现代的javascript中,我们现在可以通过执行以下操作来实现这一点。
let result = [...text.matchAll(/t(e)(s)t/g)];
我现在维护了一个同构的javascript库,它可以帮助进行很多这种类型的字符串解析。你可以在这里查看:string-saw。它有助于在使用命名捕获组时使.matchAll更易于使用。
一个例子就是
saw(text).matchAll(/t(e)(s)t/g)
它输出一个更加用户友好的匹配数组,如果你想获得更好的效果,你可以抛出命名的捕获组并获得一个对象数组。
发布于 2009-05-09 20:55:14
如果设置了global修饰符,则使用String
的match()
函数不会返回捕获的组,正如您发现的那样。
在这种情况下,您可能希望使用RegExp
对象并调用其exec()
函数。String
的match()
与RegExp
的exec()
函数global几乎完全相同,如果设置了global修饰符,普通的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
objects on the MDN的信息(具体地说,这里是the exec()
function的文档)。
https://stackoverflow.com/questions/844001
复制相似问题