diff --git a/.changeset/flat-snakes-raise.md b/.changeset/flat-snakes-raise.md new file mode 100644 index 000000000..4e1dc1be7 --- /dev/null +++ b/.changeset/flat-snakes-raise.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-regexp": patch +--- + +Improved error message and docs for `regexp/no-useless-non-capturing-group` diff --git a/docs/rules/no-useless-non-capturing-group.md b/docs/rules/no-useless-non-capturing-group.md index 870cfa953..b479c7380 100644 --- a/docs/rules/no-useless-non-capturing-group.md +++ b/docs/rules/no-useless-non-capturing-group.md @@ -17,7 +17,7 @@ since: "v0.4.0" ## :book: Rule Details -This rule reports unnecessary non-capturing group +This rule reports unnecessary non-capturing groups. Unnecessary groups are just clutter that make regexes harder to read, so they should be removed. @@ -34,6 +34,7 @@ var foo = /(?:abcd)/.test(str) var foo = /(?:[a-d])/.test(str) var foo = /(?:[a-d])|e/.test(str) var foo = /(?:a|(?:b|c)|d)/.test(str) +var foo = /a(?:b)+/.test(str) ``` @@ -49,7 +50,7 @@ var foo = /(?:a|(?:b|c)|d)/.test(str) ``` - `"allowTop"`: - Whether a top-level non-capturing group is allowed. Defaults to `"partial"`. + Whether a top-level non-capturing group is allowed (e.g. `/(?:foo|bar)/`). Defaults to `"partial"`. Sometimes it's useful to wrap a whole pattern into a non-capturing group (e.g. when the pattern is used as a building block to construct more complex patterns). Use this option to allow top-level non-capturing groups. - `"partial"`: diff --git a/lib/rules/no-useless-non-capturing-group.ts b/lib/rules/no-useless-non-capturing-group.ts index ff7e5dce9..2f21f7de9 100644 --- a/lib/rules/no-useless-non-capturing-group.ts +++ b/lib/rules/no-useless-non-capturing-group.ts @@ -49,7 +49,8 @@ export default createRule("no-useless-non-capturing-group", { }, ], messages: { - unexpected: "Unexpected quantifier Non-capturing group.", + unexpected: + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", }, type: "suggestion", // "problem", }, diff --git a/tests/lib/rules/no-useless-non-capturing-group.ts b/tests/lib/rules/no-useless-non-capturing-group.ts index 2734196a7..af6d12d3e 100644 --- a/tests/lib/rules/no-useless-non-capturing-group.ts +++ b/tests/lib/rules/no-useless-non-capturing-group.ts @@ -83,7 +83,8 @@ tester.run("no-useless-non-capturing-group", rule as any, { output: `/abcd/.test(str)`, errors: [ { - message: "Unexpected quantifier Non-capturing group.", + message: + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", line: 1, column: 2, endLine: 1, @@ -96,7 +97,8 @@ tester.run("no-useless-non-capturing-group", rule as any, { output: `/abcd/v.test(str)`, errors: [ { - message: "Unexpected quantifier Non-capturing group.", + message: + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", line: 1, column: 2, endLine: 1, @@ -109,7 +111,8 @@ tester.run("no-useless-non-capturing-group", rule as any, { output: `/[abcd]/.test(str)`, errors: [ { - message: "Unexpected quantifier Non-capturing group.", + message: + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", line: 1, column: 2, endLine: 1, @@ -120,19 +123,24 @@ tester.run("no-useless-non-capturing-group", rule as any, { { code: `/(?:ab|cd)/.test(str)`, output: `/ab|cd/.test(str)`, - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: `/a(?:ab|(?:.|a|b))/`, output: `/a(?:ab|.|a|b)/`, - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: `/(?:[abcd]+?)/.test(str)`, output: `/[abcd]+?/.test(str)`, errors: [ { - message: "Unexpected quantifier Non-capturing group.", + message: + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", line: 1, column: 2, }, @@ -143,12 +151,14 @@ tester.run("no-useless-non-capturing-group", rule as any, { output: String.raw`/0/.test(str); /\1(?:0)/.test(str); /1/.test(str); /\1(?:1)/.test(str)`, errors: [ { - message: "Unexpected quantifier Non-capturing group.", + message: + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", line: 1, column: 2, }, { - message: "Unexpected quantifier Non-capturing group.", + message: + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", line: 1, column: 42, }, @@ -157,7 +167,9 @@ tester.run("no-useless-non-capturing-group", rule as any, { { code: String.raw`/(?:a\n)/.test(str)`, output: String.raw`/a\n/.test(str)`, - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: String.raw` @@ -166,61 +178,83 @@ tester.run("no-useless-non-capturing-group", rule as any, { output: String.raw` const s = "a\\n" ;(new RegExp(s)).test(str)`, - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: String.raw` const s = "(?:a"+"\\n)" ;(new RegExp(s)).test(str)`, output: null, - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: `/(?:a)/.test(str)`, output: `/a/.test(str)`, - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: String(/(?:a)+/), output: String(/a+/), - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: String.raw`/(?:\w)/.test(str)`, output: String.raw`/\w/.test(str)`, - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: String(/(?:[abc])*/), output: String(/[abc]*/), - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: String(/foo(?:[abc]*)bar/), output: String(/foo[abc]*bar/), - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: String(/foo(?:bar)/), output: String(/foobar/), - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: `/(?:a|b)/.test(str)`, output: `/a|b/.test(str)`, - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: String(/a|(?:b|c)/), output: String(/a|b|c/), - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: String(/a|(?:b|c)/), output: String(/a|b|c/), options: [{ allowTop: "always" }], - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: ` @@ -238,7 +272,9 @@ tester.run("no-useless-non-capturing-group", rule as any, { // { allowTop: "partial" } `, options: [{ allowTop: "partial" }], - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, { code: ` @@ -250,7 +286,9 @@ tester.run("no-useless-non-capturing-group", rule as any, { `, output: null, options: [{ allowTop: "never" }], - errors: ["Unexpected quantifier Non-capturing group."], + errors: [ + "Unexpected unnecessary non-capturing group. This group can be removed without changing the behaviour of the regex.", + ], }, ], })