RegExp.prototype[Symbol.match]()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

The [Symbol.match]() method of RegExp instances specifies how String.prototype.match() should behave. In addition, its presence (or absence) can influence whether an object is regarded as a regular expression.

Try it

class RegExp1 extends RegExp {
  [Symbol.match](str) {
    const result = RegExp.prototype[Symbol.match].call(this, str);
    if (result) {
      return "VALID";
    }
    return "INVALID";
  }
}

console.log("2012-07-02".match(new RegExp1("([0-9]+)-([0-9]+)-([0-9]+)")));
// Expected output: "VALID"

Syntax

js
regexp[Symbol.match](str)

Parameters

str

A String that is a target of the match.

Return value

An Array whose contents depend on the presence or absence of the global (g) flag, or null if no matches are found.

  • If the g flag is used, all results matching the complete regular expression will be returned, but capturing groups are not included.
  • If the g flag is not used, only the first complete match and its related capturing groups are returned. In this case, match() will return the same result as RegExp.prototype.exec() (an array with some extra properties).

Description

This method is called internally in String.prototype.match().

For example, the following two examples return same result.

js
"abc".match(/a/);

/a/[Symbol.match]("abc");

If the regex is global (with the g flag), the regex's exec() method will be repeatedly called until exec() returns null. Otherwise, exec() would only be called once and its result becomes the return value of [Symbol.match]().

Because [Symbol.match]() would keep calling exec() until it returns null, and exec() would automatically reset the regex's lastIndex to 0 when the last match fails, [Symbol.match]() would typically not have side effects when it exits. However, when the regex is sticky but not global, lastIndex would not be reset. In this case, each call to match() may return a different result.

js
const re = /[abc]/y;
for (let i = 0; i < 5; i++) {
  console.log("abc".match(re), re.lastIndex);
}
// [ 'a' ] 1
// [ 'b' ] 2
// [ 'c' ] 3
// null 0
// [ 'a' ] 1

When the regex is sticky and global, it would still perform sticky matches — i.e. it would fail to match any occurrences beyond the lastIndex.

js
console.log("ab-c".match(/[abc]/gy)); // [ 'a', 'b' ]

If the current match is an empty string, the lastIndex would still be advanced — if the regex is Unicode-aware, it would advance by one Unicode code point; otherwise, it advances by one UTF-16 code unit.

js
console.log("😄".match(/(?:)/g)); // [ '', '', '' ]
console.log("😄".match(/(?:)/gu)); // [ '', '' ]

This method exists for customizing match behavior within RegExp subclasses.

In addition, the [Symbol.match] property is used to check whether an object is a regular expression.

Examples

Direct call

This method can be used in almost the same way as String.prototype.match(), except the different this and the different arguments order.

js
const re = /[0-9]+/g;
const str = "2016-01-02";
const result = re[Symbol.match](str);
console.log(result); // ["2016", "01", "02"]

Using [Symbol.match]() in subclasses

Subclasses of RegExp can override the [Symbol.match]() method to modify the default behavior.

js
class MyRegExp extends RegExp {
  [Symbol.match](str) {
    const result = RegExp.prototype[Symbol.match].call(this, str);
    if (!result) return null;
    return {
      group(n) {
        return result[n];
      },
    };
  }
}

const re = new MyRegExp("([0-9]+)-([0-9]+)-([0-9]+)");
const str = "2016-01-02";
const result = str.match(re); // String.prototype.match calls re[Symbol.match]().
console.log(result.group(1)); // 2016
console.log(result.group(2)); // 01
console.log(result.group(3)); // 02

Specifications

Specification
ECMAScript® 2025 Language Specification
# sec-regexp.prototype-%symbol.match%

Browser compatibility

Report problems with this compatibility data on GitHub
desktopmobileserver
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Deno
Node.js
[Symbol.match]

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support

See also