docs.rodeo

MDN Web Docs mirror

RegExp.prototype.exec()

{{JSRef}} 

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

{{InteractiveExample("JavaScript Demo: RegExp.prototype.exec()")}} 

const regex1 = RegExp("foo*", "g");
const str1 = "table football, foosball";
let array1;

while ((array1 = regex1.exec(str1)) !== null) {
  console.log(`Found ${array1[0]}. Next starts at ${regex1.lastIndex}.`);
  // Expected output: "Found foo. Next starts at 9."
  // Expected output: "Found foo. Next starts at 19."
}

Syntax

exec(str)

Parameters

Return value

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

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:

Description

JavaScript {{jsxref("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 {{jsxref("String.prototype.match()")}} .

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

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.

exec() is useful for complex operations that cannot be easily achieved via any of the methods above, often when you need to manually adjust lastIndex. ({{jsxref("String.prototype.matchAll()")}}  copies the regex, so changing lastIndex while iterating over matchAll does not affect the iteration.) For one such example, see rewinding lastIndex.

Examples

Using exec()

Consider the following example:

// 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");

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

Property Value
[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" }

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

Finding successive matches

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 {{jsxref("RegExp/lastIndex", "lastIndex")}}  property ({{jsxref("RegExp/test", "test()")}}  will also advance the {{jsxref("RegExp/lastIndex", "lastIndex")}}  property). Note that the {{jsxref("RegExp/lastIndex", "lastIndex")}}  property will not be reset when searching a different string, it will start its search at its existing {{jsxref("RegExp/lastIndex", "lastIndex")}} .

For example, assume you have this script:

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!

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

Using exec() with RegExp literals

You can also use exec() without creating a {{jsxref("RegExp")}}  object explicitly:

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

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

Specifications

{{Specifications}} 

Browser compatibility

{{Compat}} 

See also

In this article

View on MDN