RegExp.prototype.exec()
试一试
语法
exec(str)
参数
返回值
如果匹配失败,exec()
方法将返回 null
,并将正则表达式的 lastIndex
设置为 0
。
如果匹配成功,exec()
方法将返回一个数组,并更新正则表达式对象的 lastIndex
属性。返回的数组将匹配的文本作为第一个项目,然后为匹配文本的每个捕获组添加一个项目。该数组还具有以下其他属性
索引
-
匹配在字符串中的 0 为基的索引。
输入
-
与之匹配的原始字符串。
组
-
命名捕获组的
null
原型对象,其键是名称,值是捕获组,或undefined
(如果未定义任何命名捕获组)。有关更多信息,请参阅 捕获组。 indices
可选-
此属性仅在设置了
d
标志时存在。它是一个数组,其中每个条目都表示子字符串匹配的边界。此数组中每个元素的索引对应于exec()
返回的数组中相应的子字符串匹配的索引。换句话说,第一个indices
条目表示整个匹配,第二个indices
条目表示第一个捕获组,等等。每个条目本身都是一个包含两个元素的数组,其中第一个数字表示匹配的开始索引,第二个数字表示匹配的结束索引。indices
数组还具有一个groups
属性,该属性保存所有命名捕获组的null
原型对象。键是捕获组的名称,每个值都是一个包含两个元素的数组,第一个数字是捕获组的开始索引,第二个数字是捕获组的结束索引。如果正则表达式不包含任何命名捕获组,则groups
为undefined
。
描述
当 JavaScript RegExp
对象设置了 全局 或 粘性 标志时(例如 /foo/g
或 /foo/y
),它们是有状态的。它们存储来自先前匹配的 lastIndex
。在内部使用它,exec()
可用于迭代文本字符串中的多个匹配项(使用捕获组),而不是仅使用 String.prototype.match()
获取匹配的字符串。
在使用 exec()
时,当设置粘性标志时,全局标志没有影响 - 匹配始终是粘性的。
exec()
是正则表达式的基本方法。许多其他正则表达式方法在内部调用 exec()
- 包括由字符串方法调用的那些方法,例如 [Symbol.replace]()
。虽然 exec()
本身功能强大(而且效率最高),但它通常不能最清楚地传达意图。
- 如果您只关心正则表达式是否与字符串匹配,但不关心实际匹配的内容,请使用
RegExp.prototype.test()
。 - 如果您正在查找全局正则表达式的所有出现情况,并且不关心捕获组等信息,请使用
String.prototype.match()
。此外,String.prototype.matchAll()
通过允许您迭代匹配项来简化匹配字符串的多个部分(使用捕获组)。 - 如果您正在执行匹配以查找其在字符串中的索引位置,请使用
String.prototype.search()
方法。
示例
使用 exec()
请考虑以下示例
// 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
的状态
属性 | 值 |
---|---|
[0] |
"Quick Brown Fox Jumps" |
[1] |
"Brown" |
[2] |
"Jumps" |
索引 |
4 |
索引 |
[[4, 25], [10, 15], [20, 25]] 组:{ color: [10, 15 ]} |
输入 |
"The Quick Brown Fox Jumps Over The Lazy Dog" |
组 |
{ color: "brown" } |
此外,由于此正则表达式是全局的,re.lastIndex
将被设置为 25
。
查找连续匹配项
如果您的正则表达式使用 g
标志,则可以使用 exec()
方法多次在同一字符串中查找连续匹配项。当您这样做时,搜索将从正则表达式 lastIndex
属性指定的 str
子字符串开始 (test()
也将推进 lastIndex
属性)。请注意,当搜索不同的字符串时,lastIndex
属性不会重置,它将从其现有的 lastIndex
开始搜索。
例如,假设您有以下脚本
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()
替换此类代码,以使其不易出错。
使用带有正则表达式字面量的 exec()
您也可以使用 exec()
,而无需显式创建 RegExp
对象
const matches = /(hello \S+)/.exec("This is a hello world!");
console.log(matches[1]);
这将记录包含 'hello world!'
的消息。
规范
规范 |
---|
ECMAScript 语言规范 # sec-regexp.prototype.exec |
浏览器兼容性
BCD 表仅在浏览器中加载