Skip to content

regexResultArrayGroups

Reports indexed access on regex result arrays when named capturing groups should be used.

✅ This rule is included in the ts stylisticStrict presets.

When a regular expression has named capturing groups, accessing the matched values through .groups.name is more readable and maintainable than using numeric indices like result[1]. Numeric indices are fragile because they can break if the regex pattern is modified (e.g., adding a new capturing group before the one you’re accessing).

This rule reports indexed access on regex result arrays when the index corresponds to a named capturing group.

const regex = /a(?<foo>b)c/;
const match = regex.exec(text);
if (match) {
const value = match[1];
}
const result = "text".match(/a(?<foo>b)c/);
if (result) {
const value = result[1];
}
const matches = "text".matchAll(/a(?<foo>b)c/g);
for (const match of matches) {
const value = match[1];
}

When a regex has both named and unnamed capturing groups, only access to the named groups is reported:

const regex = /(a)(?<bar>b)c/;
const match = regex.exec(text);
if (match) {
const first = match[1];
const second = match[2];
}

Using named groups correctly:

const regex = /a(?<foo>b)c/;
const match = regex.exec(text);
if (match) {
const value = match.groups.foo;
}

Accessing unnamed capturing groups by index:

const regex = /a(b)c/;
const match = regex.exec(text);
if (match) {
const value = match[1];
}

Accessing match index 0 (the full match):

const regex = /a(?<foo>b)c/;
const match = regex.exec(text);
if (match) {
const fullMatch = match[0];
}

This rule is not configurable.

If you have a codebase that consistently uses numeric indices for all capturing groups, migrating to named groups may require significant refactoring. You might also prefer to disable this rule if you prefer the brevity of numeric indices over the clarity of named groups.

Made with ❤️‍🔥 in Boston by Josh Goldberg and contributors.