首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >JavaScript正则表达式和子匹配

JavaScript正则表达式和子匹配
EN

Stack Overflow用户
提问于 2009-05-09 20:34:09
回答 2查看 34.2K关注 0票数 72

为什么在设置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)];
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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)

它输出一个更加用户友好的匹配数组,如果你想获得更好的效果,你可以抛出命名的捕获组并获得一个对象数组。

票数 5
EN

Stack Overflow用户

发布于 2009-05-09 20:55:14

如果设置了global修饰符,则使用Stringmatch()函数不会返回捕获的组,正如您发现的那样。

在这种情况下,您可能希望使用RegExp对象并调用其exec()函数。Stringmatch()RegExpexec()函数global几乎完全相同,如果设置了global修饰符,普通的match()函数将不会返回捕获的组,而RegExpexec()函数将返回。(注意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的文档)。

票数 100
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/844001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档