JavaScript 正则表达式和子匹配

标签 javascript regex

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

最佳答案

如果设置了全局修饰符,使用 Stringmatch() 函数将不会返回捕获的组,如您所见。

在这种情况下,您可能希望使用 RegExp 对象并调用其 exec() 函数。 Stringmatch() 几乎与 RegExpexec() 函数相同……除了像这样的情况这些。如果设置了全局修饰符,普通的 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 对象的信息 on the MDN (具体来说,这是 the exec() function 的文档)。

关于JavaScript 正则表达式和子匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/844001/

相关文章:

javascript - Bluebird 用于并行独立任务

javascript - 安全访问 Immutable.js 结构中的嵌套值

javascript - backbonejs 是否像 canjs 一样使用 "live binding"?

regex - 正则表达式 - 匹配单词的一部分,但有一个异常(exception)

javascript - 在 jquery 中折叠展开

javascript - 单击“编辑”按钮不会在表格过滤器后更改页面上的 html

swift - 如何快速解析 Apache 日志文件?

不带括号的 JavaScript 交替

regex - gsub 速度与图案长度

ios - ios swift 的 FFLabel 库中的标签和属性颜色问题