RegExp.prototype.exec()
exec() 方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。
尝试一下
语法
js
exec(str)
参数
str-
要匹配正则表达式的字符串。
返回值
描述
在设置了 global 或 sticky 标志位的情况下(如 /foo/g 或 /foo/y),JavaScript RegExp 对象是有状态的。它们会将上次成功匹配后的位置记录在 lastIndex 属性中。使用此特性,exec() 可用来对单个字符串中的多次匹配结果进行逐条的遍历(包括捕获到的匹配),而相比之下, String.prototype.match() 只会返回匹配到的结果。
在使用 exec() 时,global 标志位不会在 sticky 标志位被设置时生效,而 match() 始终会设置 sticky 标志位。
exec() 是正则表达式的原始方法。许多其他的正则表达式方法会在内部调用 exec()——包括一些字符串方法也会调用 exec(),如 @@replace。虽然 exec() 本身非常强大而又有效,但它通常不能最清楚地表示调用的目的。
- 如果你只是为了判断是否匹配,请使用
RegExp.prototype.test()方法代替。 - 如果你只是为了找出所有匹配正则表达式的字符串而又不关心捕获组,请使用
String.prototype.match()方法代替。此外,String.prototype.matchAll()允许你对匹配项进行迭代,这有助于简化匹配字符串的多个部分(带有匹配组)。 - 如果你只是为了查找在字符串中匹配的索引,请使用
String.prototype.search()方法代替。
示例
使用 exec()
考虑以下示例:
js
// Match "quick brown" followed by "jumps", ignoring characters in between
// Remember "brown" and "jumps"
// Ignore case
const re = /quick\s(?<color>brown).+?(jumps)/igd;
const result = re.exec('The Quick Brown Fox Jumps Over The Lazy Dog');
下表列出这个脚本的返回值(result):
| 属性 | 值 |
|---|---|
[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" } |
另外,由于正则表达式是全局的(global),re.lastIndex 会被设置为 25。
查找所有匹配
当正则表达式设置 g 标志位时,可以多次执行 exec 方法来查找同一个字符串中的成功匹配。当你这样做时,查找将从正则表达式的 lastIndex 属性指定的位置开始。(test() 也会更新 lastIndex 属性)。注意,即使再次查找的字符串不是原查找字符串时,lastIndex 也不会被重置,它依旧会从记录的 lastIndex 开始。
例如,你使用下面的脚本:
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);
}
脚本运行结果如下:
Found abb. Next match starts at 3 Found ab. Next match starts at 9
警告: 以下情况会导致匹配变成一个无限循环!
你也可以将这类的代码替换为 String.prototype.matchAll() 以降低出错的可能性。
结合 RegExp 字面量使用 exec()
你也可以直接使用 exec() 而不是创建一个 RegExp 对象:
js
const matches = /(hello \S+)/.exec('This is a hello world!');
console.log(matches[1]);
运行上面的代码,控制台会输出 'hello world!' 字符串。
规范
| Specification |
|---|
| ECMAScript Language Specification # sec-regexp.prototype.exec |
浏览器兼容性
BCD tables only load in the browser