RegExp.prototype.exec()

RegExp 实例的 exec() 方法使用此正则表达式执行搜索以查找指定字符串中的匹配项,并返回结果数组或 null

¥The exec() method of RegExp instances executes a search with this regular expression for a match in a specified string and returns a result array, or null.

Try it

语法

¥Syntax

js
exec(str)

参数

¥Parameters

str

与正则表达式匹配的字符串。所有值都是 强制为字符串,因此省略它或传递 undefined 会导致 exec() 搜索字符串 "undefined",这很少是你想要的。

返回值

¥Return value

如果匹配失败,exec() 方法将返回 null,并将正则表达式的 lastIndex 设置为 0

¥If the match fails, the exec() method returns null, and sets the regex's lastIndex to 0.

如果匹配成功,exec() 方法返回一个数组并更新正则表达式对象的 lastIndex 属性。返回的数组将匹配的文本作为第一项,然后为匹配文本的每个捕获组提供一个项目。该数组还具有以下附加属性:

¥If the match succeeds, the exec() method returns an array and updates the lastIndex property of the regular expression object. The returned array has the matched text as the first item, and then one item for each capturing group of the matched text. The array also has the following additional properties:

index

字符串中匹配项的从 0 开始的索引。

input

匹配的原始字符串。

groups

命名捕获组的 null-原型对象,其键是名称,值是捕获组;如果未定义命名捕获组,则为 undefined。请参阅 捕获组 了解更多信息。

indices Optional

该属性仅在设置了 d 标志时才存在。它是一个数组,其中每个条目代表子字符串匹配的范围。该数组中每个元素的索引对应于 exec() 返回的数组中相应子字符串匹配的索引。换句话说,第一个 indices 条目代表整个匹配,第二个 indices 条目代表第一个捕获组,依此类推。每个条目本身都是一个双元素数组,其中第一个数字代表匹配的开始索引,第二个数字, 它的结束索引。

indices 数组另外还有一个 groups 属性,其中包含所有命名捕获组的 null-原型对象。键是捕获组的名称,每个值都是一个双元素数组,第一个数字是捕获组的起始索引,第二个数字是捕获组的结束索引。如果正则表达式不包含任何命名捕获组,则 groupsundefined

描述

¥Description

JavaScript RegExp 对象在设置了 globalsticky 标志(例如 /foo/g/foo/y)时是有状态的。他们存储了上一场比赛的 lastIndex。在内部使用此功能,exec() 可用于迭代文本字符串(带有捕获组)中的多个匹配项,而不是仅使用 String.prototype.match() 获取匹配字符串。

¥JavaScript RegExp objects are stateful when they have the global or sticky flags set (e.g. /foo/g or /foo/y). They store a lastIndex from the previous match. Using this internally, exec() can be used to iterate over multiple matches in a string of text (with capture groups), as opposed to getting just the matching strings with String.prototype.match().

当使用 exec() 时,当设置了粘性标志时,全局标志不起作用 — 匹配始终是粘性的。

¥When using exec(), the global flag has no effect when the sticky flag is set — the match is always sticky.

exec() 是正则表达式的原始方法。许多其他正则表达式方法在内部调用 exec() — 包括那些由字符串方法调用的方法,例如 [Symbol.replace]()。虽然 exec() 本身很强大(并且是最有效的),但它通常不能最清楚地传达意图。

¥exec() is the primitive method of regexps. Many other regexp methods call exec() internally — including those called by string methods, like [Symbol.replace](). While exec() itself is powerful (and is the most efficient), it often does not convey the intent most clearly.

  • 如果你只关心正则表达式是否匹配字符串,而不关心实际匹配的内容,请改用 RegExp.prototype.test()
  • 如果你正在查找全局正则表达式的所有出现,并且你不关心捕获组等信息,请改用 String.prototype.match()。此外,String.prototype.matchAll() 允许你迭代匹配,从而有助于简化字符串的多个部分(带有捕获组)的匹配。
  • 如果你要执行匹配来查找其在字符串中的索引位置,请改用 String.prototype.search() 方法。

示例

¥Examples

使用 exec()

¥Using exec()

考虑以下示例:

¥Consider the following example:

js
// Match "quick brown" followed by "jumps", ignoring characters in between
// Remember "brown" and "jumps"
// Ignore case
const re = /quick\s(?<color>brown).+?(jumps)/dgi;
const result = re.exec("The Quick Brown Fox Jumps Over The Lazy Dog");

下表显示了运行此脚本后 result 的状态:

¥The following table shows the state of result after running this script:

属性
[0] "Quick Brown Fox Jumps"
[1] "Brown"
[2] "Jumps"
index 4
indices [[4, 25], [10, 15], [20, 25]]
groups: { color: [10, 15 ]}
input "The Quick Brown Fox Jumps Over The Lazy Dog"
groups { color: "brown" }

此外,由于此正则表达式是全局的,因此 re.lastIndex 将设置为 25

¥In addition, re.lastIndex will be set to 25, due to this regex being global.

查找连续的匹配项

¥Finding successive matches

如果你的正则表达式使用 g 标志,则可以多次使用 exec() 方法来查找同一字符串中的连续匹配项。执行此操作时,搜索将从正则表达式的 lastIndex 属性指定的 str 的子字符串开始(test() 还将推进 lastIndex 属性)。请注意,搜索不同字符串时,lastIndex 属性不会重置,而是从现有的 lastIndex 开始搜索。

¥If your regular expression uses the g flag, you can use the exec() method multiple times to find successive matches in the same string. When you do so, the search starts at the substring of str specified by the regular expression's lastIndex property (test() will also advance the lastIndex property). Note that the lastIndex property will not be reset when searching a different string, it will start its search at its existing lastIndex.

例如,假设你有以下脚本:

¥For example, assume you have this script:

js
const myRe = /ab*/g;
const str = "abbcdefabh";
let myArray;
while ((myArray = myRe.exec(str)) !== null) {
  let msg = `Found ${myArray[0]}. `;
  msg += `Next match starts at ${myRe.lastIndex}`;
  console.log(msg);
}

该脚本显示以下文本:

¥This script displays the following text:

Found abb. Next match starts at 3
Found ab. Next match starts at 9

警告:有很多陷阱可能会导致无限循环!

¥Warning: There are many pitfalls that can lead to this becoming an infinite loop!

  • 不要将正则表达式文字(或 RegExp 构造函数)放在 while 条件中 - 它将为每次迭代重新创建正则表达式并重置 lastIndex
  • 确保设置了 全局 (g) 标志,否则 lastIndex 将永远不会被提前。
  • 如果正则表达式可能匹配零长度字符(例如 /^/gm),请每次手动增加其 lastIndex 以避免卡在同一个地方。

通常可以将此类代码替换为 String.prototype.matchAll(),以使其不易出错。

¥You can usually replace this kind of code with String.prototype.matchAll() to make it less error-prone.

将 exec() 与 RegExp 文字一起使用

¥Using exec() with RegExp literals

你还可以使用 exec() 而无需显式创建 RegExp 对象:

¥You can also use exec() without creating a RegExp object explicitly:

js
const matches = /(hello \S+)/.exec("This is a hello world!");
console.log(matches[1]);

这将记录一条包含 'hello world!' 的消息。

¥This will log a message containing 'hello world!'.

规范

Specification
ECMAScript Language Specification
# sec-regexp.prototype.exec

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看

¥See also