Repository: ota-meshi/eslint-plugin-regexp
Pull request #49 (2021-03-13 00:07:45)

Change config and default
- Change `plugin:regexp/recommended` config
  - Add `regexp/confusing-quantifier` rule.
  - Add `regexp/control-character-escape` rule.
  - Add `regexp/negation` rule.
  - Add `regexp/no-dupe-disjunctions` rule.
  - Add `regexp/no-empty-alternative` rule.
  - Add `regexp/no-empty-capturing-group` rule.
  - Add `regexp/no-invalid-regexp` rule.
  - Add `regexp/no-lazy-ends` rule.
  - Add `regexp/no-legacy-features` rule.
  - Add `regexp/no-non-standard-flag` rule.
  - Add `regexp/no-obscure-range` rule.
  - Add `regexp/no-optional-assertion` rule.
  - Add `regexp/no-potentially-useless-backreference` rule.
  - ~~Add `regexp/no-standalone-backslash` rule.~~
  - Add `regexp/no-super-linear-backtracking` rule.
  - Add `regexp/no-trivially-nested-assertion` rule.
  - Add `regexp/no-trivially-nested-quantifier` rule.
  - Add `regexp/no-unused-capturing-group` rule.
  - Add `regexp/no-useless-assertions` rule.
  - Add `regexp/no-useless-character-class` rule.
  - Add `regexp/no-useless-dollar-replacements` rule.
  - Add `regexp/no-useless-escape` rule.
  - Add `regexp/no-useless-flag` rule.
  - Add `regexp/no-useless-lazy` rule.
  - Add `regexp/no-useless-non-capturing-group` rule.
  - Add `regexp/no-useless-quantifier` rule.
  - Add `regexp/no-useless-range` rule.
  - Add `regexp/no-zero-quantifier` rule.
  - Add `regexp/optimal-lookaround-quantifier` rule.
  - Add `regexp/optimal-quantifier-concatenation` rule.
  - Add `regexp/prefer-character-class` rule.
  - Add `regexp/prefer-predefined-assertion` rule.
  - Add `regexp/prefer-range` rule.
  - Add `regexp/prefer-unicode-codepoint-escapes` rule.
  - Add `regexp/sort-flags` rule.
  - Add `regexp/strict` rule.
  - Add `no-empty-character-class` rule.
  - Remove `no-invalid-regexp` rule.

- Change default option
  - Change `hexadecimalEscape` option of `regexp/letter-case` rule from `ignore` to `lowercase`.
  - Change `controlEscape` option of `regexp/letter-case` rule from `ignore` to `uppercase`.

coveralls: ## Pull Request Test Coverage Report for [Build 647812750](https://coveralls.io/builds/37899945)

* **0** of **0**   changed or added relevant lines in **0** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage remained the same at **92.194%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/37899945/badge)](https://coveralls.io/builds/37899945) |
| :-- | --: |
| Change from base [Build 647783976](https://coveralls.io/builds/37899686): |  0.0% |
| Covered Lines: | 2301 |
| Relevant Lines: | 2419 |

---
##### 💛  - [Coveralls](https://coveralls.io)

RunDevelopment: I think there are 2 problems with the recommended config:

1. `regexp/strict` overlaps with 3 other rules. `regexp/strict` is a superset of `regexp/no-standalone-backslash`, `regexp/no-octal`, and `regexp/no-useless-escape`.

    I don't know whether we should remove those 3 rules from the rec config or whether we should live with double reporting in those cases.

2. `regexp/no-useless-non-capturing-group`: I love this rule but it's so annoying when writing regexes. It always tries to remove non-capturing groups and overshadows other errors while I write my regexes. It's great for code review but not so much for live editing.

    Maybe we should remove it from the rec config? I don't want people to install our plugin only to be annoyed by this rule.

    Another idea would be to make the rule less annoying. The problem is that it underlines the whole group. Maybe we could make the report range smaller (e.g. only the `(?:` part)? That way the rule wouldn't prevent me from seeing errors within the group.
ota-meshi: > regexp/strict overlaps with 3 other rules. regexp/strict is a superset of regexp/no-standalone-backslash, regexp/no-octal, and regexp/no-useless-escape.

I think it's good to turn off `regexp/no-standalone-backslash`. It rule is a complete subset of `regexp/strict`.

However, there seems to be a slight difference between `regexp/no-useless-escape` and `regexp/no-octal` from `regexp/strict`.

```js
var foo = /[\|]/; // Reported in `regexp/no-useless-escape`. But not reported in `regexp/strict`.
var foo = /[\1-\4]/; // Reported in `regexp/strict`. But not reported in `regexp/no-octal`.
```

These rules may report duplicates, but I think it's good to turn them on.


Patch:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index df6dab1..1289d83 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -127,4 +127,4 @@ Aside from `npm test`, there are also a few other ways to manually test new feat
 
 <!-- Important links -->
 
-[new-issue]: https://github.com/PrismJS/prism/issues/new/choose
+[new-issue]: https://github.com/ota-meshi/eslint-plugin-regexp/issues/new/choose
diff --git a/README.md b/README.md
index e739368..7117152 100644
--- a/README.md
+++ b/README.md
@@ -104,53 +104,53 @@ The rules with the following star :star: are included in the `plugin:regexp/reco
 
 | Rule ID | Description |    |
 |:--------|:------------|:---|
-| [regexp/no-dupe-disjunctions](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-dupe-disjunctions.html) | disallow duplicate disjunctions |  |
-| [regexp/no-empty-alternative](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-alternative.html) | disallow alternatives without elements |  |
-| [regexp/no-empty-capturing-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-capturing-group.html) | disallow capturing group that captures empty. |  |
+| [regexp/no-dupe-disjunctions](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-dupe-disjunctions.html) | disallow duplicate disjunctions | :star: |
+| [regexp/no-empty-alternative](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-alternative.html) | disallow alternatives without elements | :star: |
+| [regexp/no-empty-capturing-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-capturing-group.html) | disallow capturing group that captures empty. | :star: |
 | [regexp/no-empty-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-group.html) | disallow empty group | :star: |
 | [regexp/no-empty-lookarounds-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-empty-lookarounds-assertion.html) | disallow empty lookahead assertion or empty lookbehind assertion | :star: |
 | [regexp/no-escape-backspace](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-escape-backspace.html) | disallow escape backspace (`[\b]`) | :star: |
-| [regexp/no-invalid-regexp](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-invalid-regexp.html) | disallow invalid regular expression strings in `RegExp` constructors |  |
-| [regexp/no-lazy-ends](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-lazy-ends.html) | disallow lazy quantifiers at the end of an expression |  |
-| [regexp/no-optional-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-optional-assertion.html) | disallow optional assertions |  |
-| [regexp/no-potentially-useless-backreference](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-potentially-useless-backreference.html) | disallow backreferences that reference a group that might not be matched |  |
-| [regexp/no-super-linear-backtracking](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-super-linear-backtracking.html) | disallow exponential and polynomial backtracking | :wrench: |
+| [regexp/no-invalid-regexp](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-invalid-regexp.html) | disallow invalid regular expression strings in `RegExp` constructors | :star: |
+| [regexp/no-lazy-ends](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-lazy-ends.html) | disallow lazy quantifiers at the end of an expression | :star: |
+| [regexp/no-optional-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-optional-assertion.html) | disallow optional assertions | :star: |
+| [regexp/no-potentially-useless-backreference](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-potentially-useless-backreference.html) | disallow backreferences that reference a group that might not be matched | :star: |
+| [regexp/no-super-linear-backtracking](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-super-linear-backtracking.html) | disallow exponential and polynomial backtracking | :star::wrench: |
 | [regexp/no-super-linear-move](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-super-linear-move.html) | disallow quantifiers that cause quadratic moves |  |
-| [regexp/no-useless-assertions](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-assertions.html) | disallow assertions that are known to always accept (or reject) |  |
+| [regexp/no-useless-assertions](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-assertions.html) | disallow assertions that are known to always accept (or reject) | :star: |
 | [regexp/no-useless-backreference](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-backreference.html) | disallow useless backreferences in regular expressions | :star: |
-| [regexp/no-useless-dollar-replacements](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-dollar-replacements.html) | disallow useless `$` replacements in replacement string |  |
-| [regexp/strict](https://ota-meshi.github.io/eslint-plugin-regexp/rules/strict.html) | disallow not strictly valid regular expressions | :wrench: |
+| [regexp/no-useless-dollar-replacements](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-dollar-replacements.html) | disallow useless `$` replacements in replacement string | :star: |
+| [regexp/strict](https://ota-meshi.github.io/eslint-plugin-regexp/rules/strict.html) | disallow not strictly valid regular expressions | :star::wrench: |
 
 ### Best Practices
 
 | Rule ID | Description |    |
 |:--------|:------------|:---|
-| [regexp/confusing-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/confusing-quantifier.html) | disallow confusing quantifiers |  |
-| [regexp/control-character-escape](https://ota-meshi.github.io/eslint-plugin-regexp/rules/control-character-escape.html) | enforce consistent escaping of control characters | :wrench: |
-| [regexp/negation](https://ota-meshi.github.io/eslint-plugin-regexp/rules/negation.html) | enforce use of escapes on negation | :wrench: |
+| [regexp/confusing-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/confusing-quantifier.html) | disallow confusing quantifiers | :star: |
+| [regexp/control-character-escape](https://ota-meshi.github.io/eslint-plugin-regexp/rules/control-character-escape.html) | enforce consistent escaping of control characters | :star::wrench: |
+| [regexp/negation](https://ota-meshi.github.io/eslint-plugin-regexp/rules/negation.html) | enforce use of escapes on negation | :star::wrench: |
 | [regexp/no-dupe-characters-character-class](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-dupe-characters-character-class.html) | disallow duplicate characters in the RegExp character class | :star::wrench: |
 | [regexp/no-invisible-character](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-invisible-character.html) | disallow invisible raw character | :star::wrench: |
-| [regexp/no-legacy-features](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-legacy-features.html) | disallow legacy RegExp features |  |
-| [regexp/no-non-standard-flag](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-non-standard-flag.html) | disallow non-standard flags |  |
-| [regexp/no-obscure-range](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-obscure-range.html) | disallow obscure character ranges |  |
-| [regexp/no-octal](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-octal.html) | disallow octal escape sequence | :star: |
+| [regexp/no-legacy-features](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-legacy-features.html) | disallow legacy RegExp features | :star: |
+| [regexp/no-non-standard-flag](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-non-standard-flag.html) | disallow non-standard flags | :star: |
+| [regexp/no-obscure-range](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-obscure-range.html) | disallow obscure character ranges | :star: |
+| [regexp/no-octal](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-octal.html) | disallow octal escape sequence |  |
 | [regexp/no-standalone-backslash](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-standalone-backslash.html) | disallow standalone backslashes (`\`) |  |
-| [regexp/no-trivially-nested-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-trivially-nested-assertion.html) | disallow trivially nested assertions | :wrench: |
-| [regexp/no-trivially-nested-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-trivially-nested-quantifier.html) | disallow nested quantifiers that can be rewritten as one quantifier | :wrench: |
-| [regexp/no-unused-capturing-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-unused-capturing-group.html) | disallow unused capturing group | :wrench: |
-| [regexp/no-useless-character-class](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-character-class.html) | disallow character class with one character | :wrench: |
-| [regexp/no-useless-flag](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-flag.html) | disallow unnecessary regex flags | :wrench: |
-| [regexp/no-useless-lazy](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-lazy.html) | disallow unnecessarily non-greedy quantifiers | :wrench: |
-| [regexp/no-useless-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-quantifier.html) | disallow quantifiers that can be removed | :wrench: |
-| [regexp/no-useless-range](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-range.html) | disallow unnecessary range of characters by using a hyphen | :wrench: |
+| [regexp/no-trivially-nested-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-trivially-nested-assertion.html) | disallow trivially nested assertions | :star::wrench: |
+| [regexp/no-trivially-nested-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-trivially-nested-quantifier.html) | disallow nested quantifiers that can be rewritten as one quantifier | :star::wrench: |
+| [regexp/no-unused-capturing-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-unused-capturing-group.html) | disallow unused capturing group | :star::wrench: |
+| [regexp/no-useless-character-class](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-character-class.html) | disallow character class with one character | :star::wrench: |
+| [regexp/no-useless-flag](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-flag.html) | disallow unnecessary regex flags | :star::wrench: |
+| [regexp/no-useless-lazy](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-lazy.html) | disallow unnecessarily non-greedy quantifiers | :star::wrench: |
+| [regexp/no-useless-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-quantifier.html) | disallow quantifiers that can be removed | :star::wrench: |
+| [regexp/no-useless-range](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-range.html) | disallow unnecessary range of characters by using a hyphen | :star::wrench: |
 | [regexp/no-useless-two-nums-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-two-nums-quantifier.html) | disallow unnecessary `{n,m}` quantifier | :star::wrench: |
-| [regexp/no-zero-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-zero-quantifier.html) | disallow quantifiers with a maximum of zero |  |
-| [regexp/optimal-lookaround-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/optimal-lookaround-quantifier.html) | disallow the alternatives of lookarounds that end with a non-constant quantifier |  |
-| [regexp/optimal-quantifier-concatenation](https://ota-meshi.github.io/eslint-plugin-regexp/rules/optimal-quantifier-concatenation.html) | require optimal quantifiers for concatenated quantifiers | :wrench: |
+| [regexp/no-zero-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-zero-quantifier.html) | disallow quantifiers with a maximum of zero | :star: |
+| [regexp/optimal-lookaround-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/optimal-lookaround-quantifier.html) | disallow the alternatives of lookarounds that end with a non-constant quantifier | :star: |
+| [regexp/optimal-quantifier-concatenation](https://ota-meshi.github.io/eslint-plugin-regexp/rules/optimal-quantifier-concatenation.html) | require optimal quantifiers for concatenated quantifiers | :star::wrench: |
 | [regexp/prefer-escape-replacement-dollar-char](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-escape-replacement-dollar-char.html) | enforces escape of replacement `$` character (`$$`). |  |
-| [regexp/prefer-predefined-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-predefined-assertion.html) | prefer predefined assertion over equivalent lookarounds | :wrench: |
+| [regexp/prefer-predefined-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-predefined-assertion.html) | prefer predefined assertion over equivalent lookarounds | :star::wrench: |
 | [regexp/prefer-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-quantifier.html) | enforce using quantifier | :wrench: |
-| [regexp/prefer-range](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-range.html) | enforce using character class range | :wrench: |
+| [regexp/prefer-range](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-range.html) | enforce using character class range | :star::wrench: |
 | [regexp/prefer-regexp-exec](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-regexp-exec.html) | enforce that `RegExp#exec` is used instead of `String#match` if no global flag is provided |  |
 | [regexp/prefer-regexp-test](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-regexp-test.html) | enforce that `RegExp#test` is used instead of `String#match` and `RegExp#exec` | :wrench: |
 | [regexp/sort-alternatives](https://ota-meshi.github.io/eslint-plugin-regexp/rules/sort-alternatives.html) | sort alternatives if order doesn't matter | :wrench: |
@@ -162,18 +162,18 @@ The rules with the following star :star: are included in the `plugin:regexp/reco
 | [regexp/hexadecimal-escape](https://ota-meshi.github.io/eslint-plugin-regexp/rules/hexadecimal-escape.html) | enforce consistent usage of hexadecimal escape | :wrench: |
 | [regexp/letter-case](https://ota-meshi.github.io/eslint-plugin-regexp/rules/letter-case.html) | enforce into your favorite case | :wrench: |
 | [regexp/match-any](https://ota-meshi.github.io/eslint-plugin-regexp/rules/match-any.html) | enforce match any character style | :star::wrench: |
-| [regexp/no-useless-escape](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-escape.html) | disallow unnecessary escape characters in RegExp | :wrench: |
-| [regexp/no-useless-non-capturing-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-non-capturing-group.html) | disallow unnecessary Non-capturing group | :wrench: |
-| [regexp/prefer-character-class](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-character-class.html) | enforce using character class | :wrench: |
+| [regexp/no-useless-escape](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-escape.html) | disallow unnecessary escape characters in RegExp | :star::wrench: |
+| [regexp/no-useless-non-capturing-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-useless-non-capturing-group.html) | disallow unnecessary Non-capturing group | :star::wrench: |
+| [regexp/prefer-character-class](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-character-class.html) | enforce using character class | :star::wrench: |
 | [regexp/prefer-d](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-d.html) | enforce using `\d` | :star::wrench: |
 | [regexp/prefer-named-backreference](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-named-backreference.html) | enforce using named backreferences | :wrench: |
 | [regexp/prefer-plus-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-plus-quantifier.html) | enforce using `+` quantifier | :star::wrench: |
 | [regexp/prefer-question-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-question-quantifier.html) | enforce using `?` quantifier | :star::wrench: |
 | [regexp/prefer-star-quantifier](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-star-quantifier.html) | enforce using `*` quantifier | :star::wrench: |
-| [regexp/prefer-unicode-codepoint-escapes](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-unicode-codepoint-escapes.html) | enforce use of unicode codepoint escapes | :wrench: |
+| [regexp/prefer-unicode-codepoint-escapes](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-unicode-codepoint-escapes.html) | enforce use of unicode codepoint escapes | :star::wrench: |
 | [regexp/prefer-w](https://ota-meshi.github.io/eslint-plugin-regexp/rules/prefer-w.html) | enforce using `\w` | :star::wrench: |
 | [regexp/sort-character-class-elements](https://ota-meshi.github.io/eslint-plugin-regexp/rules/sort-character-class-elements.html) | enforces elements order in character class | :wrench: |
-| [regexp/sort-flags](https://ota-meshi.github.io/eslint-plugin-regexp/rules/sort-flags.html) | require regex flags to be sorted | :wrench: |
+| [regexp/sort-flags](https://ota-meshi.github.io/eslint-plugin-regexp/rules/sort-flags.html) | require regex flags to be sorted | :star::wrench: |
 | [regexp/unicode-escape](https://ota-meshi.github.io/eslint-plugin-regexp/rules/unicode-escape.html) | enforce consistent usage of unicode escape or unicode codepoint escape | :wrench: |
 
 ### Deprecated
diff --git a/docs/rules/README.md b/docs/rules/README.md
index cd2453d..c0396fe 100644
--- a/docs/rules/README.md
+++ b/docs/rules/README.md
@@ -13,53 +13,53 @@ The rules with the following star :star: are included in the `plugin:regexp/reco
 
 | Rule ID | Description |    |
 |:--------|:------------|:---|
-| [regexp/no-dupe-disjunctions](./no-dupe-disjunctions.md) | disallow duplicate disjunctions |  |
-| [regexp/no-empty-alternative](./no-empty-alternative.md) | disallow alternatives without elements |  |
-| [regexp/no-empty-capturing-group](./no-empty-capturing-group.md) | disallow capturing group that captures empty. |  |
+| [regexp/no-dupe-disjunctions](./no-dupe-disjunctions.md) | disallow duplicate disjunctions | :star: |
+| [regexp/no-empty-alternative](./no-empty-alternative.md) | disallow alternatives without elements | :star: |
+| [regexp/no-empty-capturing-group](./no-empty-capturing-group.md) | disallow capturing group that captures empty. | :star: |
 | [regexp/no-empty-group](./no-empty-group.md) | disallow empty group | :star: |
 | [regexp/no-empty-lookarounds-assertion](./no-empty-lookarounds-assertion.md) | disallow empty lookahead assertion or empty lookbehind assertion | :star: |
 | [regexp/no-escape-backspace](./no-escape-backspace.md) | disallow escape backspace (`[\b]`) | :star: |
-| [regexp/no-invalid-regexp](./no-invalid-regexp.md) | disallow invalid regular expression strings in `RegExp` constructors |  |
-| [regexp/no-lazy-ends](./no-lazy-ends.md) | disallow lazy quantifiers at the end of an expression |  |
-| [regexp/no-optional-assertion](./no-optional-assertion.md) | disallow optional assertions |  |
-| [regexp/no-potentially-useless-backreference](./no-potentially-useless-backreference.md) | disallow backreferences that reference a group that might not be matched |  |
-| [regexp/no-super-linear-backtracking](./no-super-linear-backtracking.md) | disallow exponential and polynomial backtracking | :wrench: |
+| [regexp/no-invalid-regexp](./no-invalid-regexp.md) | disallow invalid regular expression strings in `RegExp` constructors | :star: |
+| [regexp/no-lazy-ends](./no-lazy-ends.md) | disallow lazy quantifiers at the end of an expression | :star: |
+| [regexp/no-optional-assertion](./no-optional-assertion.md) | disallow optional assertions | :star: |
+| [regexp/no-potentially-useless-backreference](./no-potentially-useless-backreference.md) | disallow backreferences that reference a group that might not be matched | :star: |
+| [regexp/no-super-linear-backtracking](./no-super-linear-backtracking.md) | disallow exponential and polynomial backtracking | :star::wrench: |
 | [regexp/no-super-linear-move](./no-super-linear-move.md) | disallow quantifiers that cause quadratic moves |  |
-| [regexp/no-useless-assertions](./no-useless-assertions.md) | disallow assertions that are known to always accept (or reject) |  |
+| [regexp/no-useless-assertions](./no-useless-assertions.md) | disallow assertions that are known to always accept (or reject) | :star: |
 | [regexp/no-useless-backreference](./no-useless-backreference.md) | disallow useless backreferences in regular expressions | :star: |
-| [regexp/no-useless-dollar-replacements](./no-useless-dollar-replacements.md) | disallow useless `$` replacements in replacement string |  |
-| [regexp/strict](./strict.md) | disallow not strictly valid regular expressions | :wrench: |
+| [regexp/no-useless-dollar-replacements](./no-useless-dollar-replacements.md) | disallow useless `$` replacements in replacement string | :star: |
+| [regexp/strict](./strict.md) | disallow not strictly valid regular expressions | :star::wrench: |
 
 ### Best Practices
 
 | Rule ID | Description |    |
 |:--------|:------------|:---|
-| [regexp/confusing-quantifier](./confusing-quantifier.md) | disallow confusing quantifiers |  |
-| [regexp/control-character-escape](./control-character-escape.md) | enforce consistent escaping of control characters | :wrench: |
-| [regexp/negation](./negation.md) | enforce use of escapes on negation | :wrench: |
+| [regexp/confusing-quantifier](./confusing-quantifier.md) | disallow confusing quantifiers | :star: |
+| [regexp/control-character-escape](./control-character-escape.md) | enforce consistent escaping of control characters | :star::wrench: |
+| [regexp/negation](./negation.md) | enforce use of escapes on negation | :star::wrench: |
 | [regexp/no-dupe-characters-character-class](./no-dupe-characters-character-class.md) | disallow duplicate characters in the RegExp character class | :star::wrench: |
 | [regexp/no-invisible-character](./no-invisible-character.md) | disallow invisible raw character | :star::wrench: |
-| [regexp/no-legacy-features](./no-legacy-features.md) | disallow legacy RegExp features |  |
-| [regexp/no-non-standard-flag](./no-non-standard-flag.md) | disallow non-standard flags |  |
-| [regexp/no-obscure-range](./no-obscure-range.md) | disallow obscure character ranges |  |
-| [regexp/no-octal](./no-octal.md) | disallow octal escape sequence | :star: |
+| [regexp/no-legacy-features](./no-legacy-features.md) | disallow legacy RegExp features | :star: |
+| [regexp/no-non-standard-flag](./no-non-standard-flag.md) | disallow non-standard flags | :star: |
+| [regexp/no-obscure-range](./no-obscure-range.md) | disallow obscure character ranges | :star: |
+| [regexp/no-octal](./no-octal.md) | disallow octal escape sequence |  |
 | [regexp/no-standalone-backslash](./no-standalone-backslash.md) | disallow standalone backslashes (`\`) |  |
-| [regexp/no-trivially-nested-assertion](./no-trivially-nested-assertion.md) | disallow trivially nested assertions | :wrench: |
-| [regexp/no-trivially-nested-quantifier](./no-trivially-nested-quantifier.md) | disallow nested quantifiers that can be rewritten as one quantifier | :wrench: |
-| [regexp/no-unused-capturing-group](./no-unused-capturing-group.md) | disallow unused capturing group | :wrench: |
-| [regexp/no-useless-character-class](./no-useless-character-class.md) | disallow character class with one character | :wrench: |
-| [regexp/no-useless-flag](./no-useless-flag.md) | disallow unnecessary regex flags | :wrench: |
-| [regexp/no-useless-lazy](./no-useless-lazy.md) | disallow unnecessarily non-greedy quantifiers | :wrench: |
-| [regexp/no-useless-quantifier](./no-useless-quantifier.md) | disallow quantifiers that can be removed | :wrench: |
-| [regexp/no-useless-range](./no-useless-range.md) | disallow unnecessary range of characters by using a hyphen | :wrench: |
+| [regexp/no-trivially-nested-assertion](./no-trivially-nested-assertion.md) | disallow trivially nested assertions | :star::wrench: |
+| [regexp/no-trivially-nested-quantifier](./no-trivially-nested-quantifier.md) | disallow nested quantifiers that can be rewritten as one quantifier | :star::wrench: |
+| [regexp/no-unused-capturing-group](./no-unused-capturing-group.md) | disallow unused capturing group | :star::wrench: |
+| [regexp/no-useless-character-class](./no-useless-character-class.md) | disallow character class with one character | :star::wrench: |
+| [regexp/no-useless-flag](./no-useless-flag.md) | disallow unnecessary regex flags | :star::wrench: |
+| [regexp/no-useless-lazy](./no-useless-lazy.md) | disallow unnecessarily non-greedy quantifiers | :star::wrench: |
+| [regexp/no-useless-quantifier](./no-useless-quantifier.md) | disallow quantifiers that can be removed | :star::wrench: |
+| [regexp/no-useless-range](./no-useless-range.md) | disallow unnecessary range of characters by using a hyphen | :star::wrench: |
 | [regexp/no-useless-two-nums-quantifier](./no-useless-two-nums-quantifier.md) | disallow unnecessary `{n,m}` quantifier | :star::wrench: |
-| [regexp/no-zero-quantifier](./no-zero-quantifier.md) | disallow quantifiers with a maximum of zero |  |
-| [regexp/optimal-lookaround-quantifier](./optimal-lookaround-quantifier.md) | disallow the alternatives of lookarounds that end with a non-constant quantifier |  |
-| [regexp/optimal-quantifier-concatenation](./optimal-quantifier-concatenation.md) | require optimal quantifiers for concatenated quantifiers | :wrench: |
+| [regexp/no-zero-quantifier](./no-zero-quantifier.md) | disallow quantifiers with a maximum of zero | :star: |
+| [regexp/optimal-lookaround-quantifier](./optimal-lookaround-quantifier.md) | disallow the alternatives of lookarounds that end with a non-constant quantifier | :star: |
+| [regexp/optimal-quantifier-concatenation](./optimal-quantifier-concatenation.md) | require optimal quantifiers for concatenated quantifiers | :star::wrench: |
 | [regexp/prefer-escape-replacement-dollar-char](./prefer-escape-replacement-dollar-char.md) | enforces escape of replacement `$` character (`$$`). |  |
-| [regexp/prefer-predefined-assertion](./prefer-predefined-assertion.md) | prefer predefined assertion over equivalent lookarounds | :wrench: |
+| [regexp/prefer-predefined-assertion](./prefer-predefined-assertion.md) | prefer predefined assertion over equivalent lookarounds | :star::wrench: |
 | [regexp/prefer-quantifier](./prefer-quantifier.md) | enforce using quantifier | :wrench: |
-| [regexp/prefer-range](./prefer-range.md) | enforce using character class range | :wrench: |
+| [regexp/prefer-range](./prefer-range.md) | enforce using character class range | :star::wrench: |
 | [regexp/prefer-regexp-exec](./prefer-regexp-exec.md) | enforce that `RegExp#exec` is used instead of `String#match` if no global flag is provided |  |
 | [regexp/prefer-regexp-test](./prefer-regexp-test.md) | enforce that `RegExp#test` is used instead of `String#match` and `RegExp#exec` | :wrench: |
 | [regexp/sort-alternatives](./sort-alternatives.md) | sort alternatives if order doesn't matter | :wrench: |
@@ -71,18 +71,18 @@ The rules with the following star :star: are included in the `plugin:regexp/reco
 | [regexp/hexadecimal-escape](./hexadecimal-escape.md) | enforce consistent usage of hexadecimal escape | :wrench: |
 | [regexp/letter-case](./letter-case.md) | enforce into your favorite case | :wrench: |
 | [regexp/match-any](./match-any.md) | enforce match any character style | :star::wrench: |
-| [regexp/no-useless-escape](./no-useless-escape.md) | disallow unnecessary escape characters in RegExp | :wrench: |
-| [regexp/no-useless-non-capturing-group](./no-useless-non-capturing-group.md) | disallow unnecessary Non-capturing group | :wrench: |
-| [regexp/prefer-character-class](./prefer-character-class.md) | enforce using character class | :wrench: |
+| [regexp/no-useless-escape](./no-useless-escape.md) | disallow unnecessary escape characters in RegExp | :star::wrench: |
+| [regexp/no-useless-non-capturing-group](./no-useless-non-capturing-group.md) | disallow unnecessary Non-capturing group | :star::wrench: |
+| [regexp/prefer-character-class](./prefer-character-class.md) | enforce using character class | :star::wrench: |
 | [regexp/prefer-d](./prefer-d.md) | enforce using `\d` | :star::wrench: |
 | [regexp/prefer-named-backreference](./prefer-named-backreference.md) | enforce using named backreferences | :wrench: |
 | [regexp/prefer-plus-quantifier](./prefer-plus-quantifier.md) | enforce using `+` quantifier | :star::wrench: |
 | [regexp/prefer-question-quantifier](./prefer-question-quantifier.md) | enforce using `?` quantifier | :star::wrench: |
 | [regexp/prefer-star-quantifier](./prefer-star-quantifier.md) | enforce using `*` quantifier | :star::wrench: |
-| [regexp/prefer-unicode-codepoint-escapes](./prefer-unicode-codepoint-escapes.md) | enforce use of unicode codepoint escapes | :wrench: |
+| [regexp/prefer-unicode-codepoint-escapes](./prefer-unicode-codepoint-escapes.md) | enforce use of unicode codepoint escapes | :star::wrench: |
 | [regexp/prefer-w](./prefer-w.md) | enforce using `\w` | :star::wrench: |
 | [regexp/sort-character-class-elements](./sort-character-class-elements.md) | enforces elements order in character class | :wrench: |
-| [regexp/sort-flags](./sort-flags.md) | require regex flags to be sorted | :wrench: |
+| [regexp/sort-flags](./sort-flags.md) | require regex flags to be sorted | :star::wrench: |
 | [regexp/unicode-escape](./unicode-escape.md) | enforce consistent usage of unicode escape or unicode codepoint escape | :wrench: |
 
 ### Deprecated
diff --git a/docs/rules/confusing-quantifier.md b/docs/rules/confusing-quantifier.md
index a908363..ef7c9e3 100644
--- a/docs/rules/confusing-quantifier.md
+++ b/docs/rules/confusing-quantifier.md
@@ -9,6 +9,8 @@ since: "v0.8.0"
 
 > disallow confusing quantifiers
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 Confusing quantifiers are ones which imply one thing but don't deliver on that.
diff --git a/docs/rules/control-character-escape.md b/docs/rules/control-character-escape.md
index 2ddffd2..b85184e 100644
--- a/docs/rules/control-character-escape.md
+++ b/docs/rules/control-character-escape.md
@@ -9,6 +9,7 @@ since: "v0.9.0"
 
 > enforce consistent escaping of control characters
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/letter-case.md b/docs/rules/letter-case.md
index f62165b..a2ac41c 100644
--- a/docs/rules/letter-case.md
+++ b/docs/rules/letter-case.md
@@ -42,8 +42,8 @@ var foo = /\ca/
   "regexp/letter-case": ["error", {
     "caseInsensitive": "lowercase", // or "uppercase" or "ignore"
     "unicodeEscape": "lowercase", // or "uppercase" or "ignore"
-    "hexadecimalEscape": "ignore", // or "lowercase" or "uppercase"
-    "controlEscape": "ignore", // or "lowercase" or "uppercase"
+    "hexadecimalEscape": "lowercase", // or "uppercase" or "ignore"
+    "controlEscape": "uppercase", // or "lowercase" or "ignore"
   }]
 }
 ```
@@ -55,10 +55,8 @@ var foo = /\ca/
 - Properties
   - `caseInsensitive` ... Specifies the letter case when the `i` flag is present. Default is `"lowercase"`.
   - `unicodeEscape` ... Specifies the letter case when the unicode escapes. Default is `"lowercase"`.
-  - `hexadecimalEscape` ... Specifies the letter case when the hexadecimal escapes. Default is `"ignore"`.  
-    (The default value will change to `"lowercase"` in the next major version.)
-  - `controlEscape` ... Specifies the letter case when the control escapes (e.g. `\cX`). Default is `"ignore"`.  
-    (The default value will change to `"uppercase"` in the next major version.)
+  - `hexadecimalEscape` ... Specifies the letter case when the hexadecimal escapes. Default is `"ignolowercasere"`.
+  - `controlEscape` ... Specifies the letter case when the control escapes (e.g. `\cX`). Default is `"uppercase"`.
 
 ## :rocket: Version
 
diff --git a/docs/rules/negation.md b/docs/rules/negation.md
index d29fa6f..aba8bef 100644
--- a/docs/rules/negation.md
+++ b/docs/rules/negation.md
@@ -9,6 +9,7 @@ since: "v0.4.0"
 
 > enforce use of escapes on negation
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-dupe-disjunctions.md b/docs/rules/no-dupe-disjunctions.md
index 9cce3a2..2798593 100644
--- a/docs/rules/no-dupe-disjunctions.md
+++ b/docs/rules/no-dupe-disjunctions.md
@@ -9,6 +9,8 @@ since: "v0.4.0"
 
 > disallow duplicate disjunctions
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 This rule disallows duplicate disjunctions.
diff --git a/docs/rules/no-empty-alternative.md b/docs/rules/no-empty-alternative.md
index 74514f1..94ed9b8 100644
--- a/docs/rules/no-empty-alternative.md
+++ b/docs/rules/no-empty-alternative.md
@@ -9,6 +9,8 @@ since: "v0.8.0"
 
 > disallow alternatives without elements
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 While (re-)writing long regular expressions, it can happen that one forgets to
diff --git a/docs/rules/no-empty-capturing-group.md b/docs/rules/no-empty-capturing-group.md
index 881acc7..72f2a14 100644
--- a/docs/rules/no-empty-capturing-group.md
+++ b/docs/rules/no-empty-capturing-group.md
@@ -9,6 +9,8 @@ since: "v0.12.0"
 
 > disallow capturing group that captures empty.
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 This rule reports capturing group that captures assertions.
diff --git a/docs/rules/no-invalid-regexp.md b/docs/rules/no-invalid-regexp.md
index a5b588b..2354c20 100644
--- a/docs/rules/no-invalid-regexp.md
+++ b/docs/rules/no-invalid-regexp.md
@@ -9,6 +9,7 @@ description: "disallow invalid regular expression strings in `RegExp` constructo
 > disallow invalid regular expression strings in `RegExp` constructors
 
 - :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge>
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 
 ## :book: Rule Details
 
diff --git a/docs/rules/no-lazy-ends.md b/docs/rules/no-lazy-ends.md
index 9b62818..860a1f6 100644
--- a/docs/rules/no-lazy-ends.md
+++ b/docs/rules/no-lazy-ends.md
@@ -9,6 +9,8 @@ since: "v0.8.0"
 
 > disallow lazy quantifiers at the end of an expression
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 If a lazily quantified element is the last element matched by an expression
diff --git a/docs/rules/no-legacy-features.md b/docs/rules/no-legacy-features.md
index 389f9be..8ead657 100644
--- a/docs/rules/no-legacy-features.md
+++ b/docs/rules/no-legacy-features.md
@@ -9,6 +9,8 @@ since: "v0.6.0"
 
 > disallow legacy RegExp features
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 This rule disallow legacy RegExp features.
diff --git a/docs/rules/no-non-standard-flag.md b/docs/rules/no-non-standard-flag.md
index 0c7f09d..a5649a6 100644
--- a/docs/rules/no-non-standard-flag.md
+++ b/docs/rules/no-non-standard-flag.md
@@ -9,6 +9,8 @@ since: "v0.9.0"
 
 > disallow non-standard flags
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 This rule reports non-standard flags.
diff --git a/docs/rules/no-obscure-range.md b/docs/rules/no-obscure-range.md
index b86e463..e359064 100644
--- a/docs/rules/no-obscure-range.md
+++ b/docs/rules/no-obscure-range.md
@@ -9,6 +9,8 @@ since: "v0.9.0"
 
 > disallow obscure character ranges
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 The character range operator (the `-` inside character classes) can easily be misused (mostly unintentionally) to construct non-obvious character class. This rule will disallow all non-obvious uses of the character range operator.
diff --git a/docs/rules/no-octal.md b/docs/rules/no-octal.md
index 64190ca..c7f03f9 100644
--- a/docs/rules/no-octal.md
+++ b/docs/rules/no-octal.md
@@ -9,8 +9,6 @@ since: "v0.1.0"
 
 > disallow octal escape sequence
 
-- :gear: This rule is included in `"plugin:regexp/recommended"`.
-
 ## :book: Rule Details
 
 This rule reports octal escapes.
diff --git a/docs/rules/no-optional-assertion.md b/docs/rules/no-optional-assertion.md
index 390e96d..26feda8 100644
--- a/docs/rules/no-optional-assertion.md
+++ b/docs/rules/no-optional-assertion.md
@@ -9,6 +9,8 @@ since: "v0.9.0"
 
 > disallow optional assertions
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 Assertions that are quantified (directly or indirectly) can be considered optional if the quantifier has a minimum of zero.
diff --git a/docs/rules/no-potentially-useless-backreference.md b/docs/rules/no-potentially-useless-backreference.md
index 80fc0a6..e529efb 100644
--- a/docs/rules/no-potentially-useless-backreference.md
+++ b/docs/rules/no-potentially-useless-backreference.md
@@ -9,6 +9,8 @@ since: "v0.9.0"
 
 > disallow backreferences that reference a group that might not be matched
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 If the referenced group of a backreference is not matched because some other path leads to the backreference, the backreference will trivially accept (e.g. `/(?:(a)|b)\1/`). The same will happen if the captured text of the referenced group was reset before reaching the backreference.
diff --git a/docs/rules/no-super-linear-backtracking.md b/docs/rules/no-super-linear-backtracking.md
index 55e0d06..9840e0e 100644
--- a/docs/rules/no-super-linear-backtracking.md
+++ b/docs/rules/no-super-linear-backtracking.md
@@ -9,6 +9,7 @@ since: "v0.13.0"
 
 > disallow exponential and polynomial backtracking
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-trivially-nested-assertion.md b/docs/rules/no-trivially-nested-assertion.md
index 1f5e6d5..3f9b03a 100644
--- a/docs/rules/no-trivially-nested-assertion.md
+++ b/docs/rules/no-trivially-nested-assertion.md
@@ -9,6 +9,7 @@ since: "v0.9.0"
 
 > disallow trivially nested assertions
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-trivially-nested-quantifier.md b/docs/rules/no-trivially-nested-quantifier.md
index e4a20fd..192e490 100644
--- a/docs/rules/no-trivially-nested-quantifier.md
+++ b/docs/rules/no-trivially-nested-quantifier.md
@@ -9,6 +9,7 @@ since: "v0.9.0"
 
 > disallow nested quantifiers that can be rewritten as one quantifier
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-unused-capturing-group.md b/docs/rules/no-unused-capturing-group.md
index 1ad5f26..589fef0 100644
--- a/docs/rules/no-unused-capturing-group.md
+++ b/docs/rules/no-unused-capturing-group.md
@@ -9,6 +9,7 @@ since: "v0.6.0"
 
 > disallow unused capturing group
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-useless-assertions.md b/docs/rules/no-useless-assertions.md
index 01415bf..937fb96 100644
--- a/docs/rules/no-useless-assertions.md
+++ b/docs/rules/no-useless-assertions.md
@@ -9,6 +9,8 @@ since: "v0.9.0"
 
 > disallow assertions that are known to always accept (or reject)
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 Some assertion are unnecessary because the rest of the pattern forces them to
diff --git a/docs/rules/no-useless-character-class.md b/docs/rules/no-useless-character-class.md
index 732ca22..1db511c 100644
--- a/docs/rules/no-useless-character-class.md
+++ b/docs/rules/no-useless-character-class.md
@@ -9,6 +9,7 @@ since: "v0.3.0"
 
 > disallow character class with one character
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-useless-dollar-replacements.md b/docs/rules/no-useless-dollar-replacements.md
index c009e34..0198956 100644
--- a/docs/rules/no-useless-dollar-replacements.md
+++ b/docs/rules/no-useless-dollar-replacements.md
@@ -9,6 +9,8 @@ since: "v0.6.0"
 
 > disallow useless `$` replacements in replacement string
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 This rule aims to detect and disallow useless `$` replacements in regular expression replacements.
diff --git a/docs/rules/no-useless-escape.md b/docs/rules/no-useless-escape.md
index 2e4b366..fc5130b 100644
--- a/docs/rules/no-useless-escape.md
+++ b/docs/rules/no-useless-escape.md
@@ -9,6 +9,7 @@ since: "v0.4.0"
 
 > disallow unnecessary escape characters in RegExp
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-useless-flag.md b/docs/rules/no-useless-flag.md
index b48ae41..afe1c3e 100644
--- a/docs/rules/no-useless-flag.md
+++ b/docs/rules/no-useless-flag.md
@@ -9,6 +9,7 @@ since: "v0.9.0"
 
 > disallow unnecessary regex flags
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-useless-lazy.md b/docs/rules/no-useless-lazy.md
index 99e5487..b06b05c 100644
--- a/docs/rules/no-useless-lazy.md
+++ b/docs/rules/no-useless-lazy.md
@@ -9,6 +9,7 @@ since: "v0.10.0"
 
 > disallow unnecessarily non-greedy quantifiers
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-useless-non-capturing-group.md b/docs/rules/no-useless-non-capturing-group.md
index 6ce1ba0..0257803 100644
--- a/docs/rules/no-useless-non-capturing-group.md
+++ b/docs/rules/no-useless-non-capturing-group.md
@@ -9,6 +9,7 @@ since: "v0.4.0"
 
 > disallow unnecessary Non-capturing group
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-useless-quantifier.md b/docs/rules/no-useless-quantifier.md
index 27c45f8..1f4679c 100644
--- a/docs/rules/no-useless-quantifier.md
+++ b/docs/rules/no-useless-quantifier.md
@@ -9,6 +9,7 @@ since: "v0.10.0"
 
 > disallow quantifiers that can be removed
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-useless-range.md b/docs/rules/no-useless-range.md
index c4e1278..f57b9a7 100644
--- a/docs/rules/no-useless-range.md
+++ b/docs/rules/no-useless-range.md
@@ -9,6 +9,7 @@ since: "v0.3.0"
 
 > disallow unnecessary range of characters by using a hyphen
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/no-zero-quantifier.md b/docs/rules/no-zero-quantifier.md
index 064d40e..59f4b87 100644
--- a/docs/rules/no-zero-quantifier.md
+++ b/docs/rules/no-zero-quantifier.md
@@ -9,6 +9,8 @@ since: "v0.10.0"
 
 > disallow quantifiers with a maximum of zero
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 This rule reports quantifiers with a maximum of zero. These quantifiers trivially do not affect the pattern is any way and can be removed.
diff --git a/docs/rules/optimal-lookaround-quantifier.md b/docs/rules/optimal-lookaround-quantifier.md
index 95c0acf..424c733 100644
--- a/docs/rules/optimal-lookaround-quantifier.md
+++ b/docs/rules/optimal-lookaround-quantifier.md
@@ -9,6 +9,8 @@ since: "v0.8.0"
 
 > disallow the alternatives of lookarounds that end with a non-constant quantifier
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
+
 ## :book: Rule Details
 
 Non-constant quantifiers are quantifiers that describe a range (e.g. `?`, `*`,
diff --git a/docs/rules/optimal-quantifier-concatenation.md b/docs/rules/optimal-quantifier-concatenation.md
index c5ad2b9..77cb275 100644
--- a/docs/rules/optimal-quantifier-concatenation.md
+++ b/docs/rules/optimal-quantifier-concatenation.md
@@ -9,6 +9,7 @@ since: "v0.11.0"
 
 > require optimal quantifiers for concatenated quantifiers
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/prefer-character-class.md b/docs/rules/prefer-character-class.md
index 0b7f5bd..4a3d0d0 100644
--- a/docs/rules/prefer-character-class.md
+++ b/docs/rules/prefer-character-class.md
@@ -9,6 +9,7 @@ since: "v0.4.0"
 
 > enforce using character class
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/prefer-predefined-assertion.md b/docs/rules/prefer-predefined-assertion.md
index a2d897f..c48bd19 100644
--- a/docs/rules/prefer-predefined-assertion.md
+++ b/docs/rules/prefer-predefined-assertion.md
@@ -9,6 +9,7 @@ since: "v0.10.0"
 
 > prefer predefined assertion over equivalent lookarounds
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/prefer-range.md b/docs/rules/prefer-range.md
index faeb202..80468fa 100644
--- a/docs/rules/prefer-range.md
+++ b/docs/rules/prefer-range.md
@@ -9,6 +9,7 @@ since: "v0.4.0"
 
 > enforce using character class range
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/prefer-unicode-codepoint-escapes.md b/docs/rules/prefer-unicode-codepoint-escapes.md
index 2a2783f..a47f8c8 100644
--- a/docs/rules/prefer-unicode-codepoint-escapes.md
+++ b/docs/rules/prefer-unicode-codepoint-escapes.md
@@ -9,6 +9,7 @@ since: "v0.3.0"
 
 > enforce use of unicode codepoint escapes
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/sort-flags.md b/docs/rules/sort-flags.md
index 9c1a84b..e2fad28 100644
--- a/docs/rules/sort-flags.md
+++ b/docs/rules/sort-flags.md
@@ -9,6 +9,7 @@ since: "v0.9.0"
 
 > require regex flags to be sorted
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/strict.md b/docs/rules/strict.md
index 16d926b..48a34ab 100644
--- a/docs/rules/strict.md
+++ b/docs/rules/strict.md
@@ -9,6 +9,7 @@ since: "v0.12.0"
 
 > disallow not strictly valid regular expressions
 
+- :gear: This rule is included in `"plugin:regexp/recommended"`.
 - :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/lib/configs/recommended.ts b/lib/configs/recommended.ts
index b8c0c1f..ab19b6d 100644
--- a/lib/configs/recommended.ts
+++ b/lib/configs/recommended.ts
@@ -3,27 +3,62 @@ export = {
     rules: {
         // ESLint core rules
         "no-control-regex": "error",
-        "no-invalid-regexp": "error",
+        "no-empty-character-class": "error",
         "no-misleading-character-class": "error",
         "no-regex-spaces": "error",
         "prefer-regex-literals": "error",
         // The ESLint rule will report fewer cases than our rule
+        "no-invalid-regexp": "off",
         "no-useless-backreference": "off",
 
         // eslint-plugin-regexp rules
+        "regexp/confusing-quantifier": "warn",
+        "regexp/control-character-escape": "error",
         "regexp/match-any": "error",
+        "regexp/negation": "error",
         "regexp/no-dupe-characters-character-class": "error",
+        "regexp/no-dupe-disjunctions": "error",
+        "regexp/no-empty-alternative": "warn",
+        "regexp/no-empty-capturing-group": "error",
         "regexp/no-empty-group": "error",
         "regexp/no-empty-lookarounds-assertion": "error",
         "regexp/no-escape-backspace": "error",
+        "regexp/no-invalid-regexp": "error",
         "regexp/no-invisible-character": "error",
-        "regexp/no-octal": "error",
+        "regexp/no-lazy-ends": "warn",
+        "regexp/no-legacy-features": "error",
+        "regexp/no-non-standard-flag": "error",
+        "regexp/no-obscure-range": "error",
+        "regexp/no-optional-assertion": "error",
+        "regexp/no-potentially-useless-backreference": "warn",
+        "regexp/no-super-linear-backtracking": "error",
+        "regexp/no-trivially-nested-assertion": "error",
+        "regexp/no-trivially-nested-quantifier": "error",
+        "regexp/no-unused-capturing-group": "error",
+        "regexp/no-useless-assertions": "error",
         "regexp/no-useless-backreference": "error",
+        "regexp/no-useless-character-class": "error",
+        "regexp/no-useless-dollar-replacements": "error",
+        "regexp/no-useless-escape": "error",
+        "regexp/no-useless-flag": "warn",
+        "regexp/no-useless-lazy": "error",
+        "regexp/no-useless-non-capturing-group": "error",
+        "regexp/no-useless-quantifier": "error",
+        "regexp/no-useless-range": "error",
         "regexp/no-useless-two-nums-quantifier": "error",
+        "regexp/no-zero-quantifier": "error",
+        "regexp/optimal-lookaround-quantifier": "warn",
+        "regexp/optimal-quantifier-concatenation": "error",
+        "regexp/prefer-character-class": "error",
         "regexp/prefer-d": "error",
         "regexp/prefer-plus-quantifier": "error",
+        "regexp/prefer-predefined-assertion": "error",
         "regexp/prefer-question-quantifier": "error",
+        "regexp/prefer-range": "error",
         "regexp/prefer-star-quantifier": "error",
+        "regexp/prefer-unicode-codepoint-escapes": "error",
         "regexp/prefer-w": "error",
+        "regexp/sort-flags": "error",
+        "regexp/strict": "error",
     },
 }
diff --git a/lib/rules/confusing-quantifier.ts b/lib/rules/confusing-quantifier.ts
index 4a539f0..eec83ca 100644
--- a/lib/rules/confusing-quantifier.ts
+++ b/lib/rules/confusing-quantifier.ts
@@ -13,9 +13,7 @@ export default createRule("confusing-quantifier", {
         docs: {
             description: "disallow confusing quantifiers",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
             default: "warn",
         },
         schema: [],
diff --git a/lib/rules/control-character-escape.ts b/lib/rules/control-character-escape.ts
index ebaf5b2..a131ee2 100644
--- a/lib/rules/control-character-escape.ts
+++ b/lib/rules/control-character-escape.ts
@@ -26,9 +26,7 @@ export default createRule("control-character-escape", {
         docs: {
             description: "enforce consistent escaping of control characters",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
diff --git a/lib/rules/letter-case.ts b/lib/rules/letter-case.ts
index 13b7f40..f4027d3 100644
--- a/lib/rules/letter-case.ts
+++ b/lib/rules/letter-case.ts
@@ -17,11 +17,8 @@ type Case = typeof CASE_SCHEMA[number]
 const DEFAULTS = {
     caseInsensitive: "lowercase" as const,
     unicodeEscape: "lowercase" as const,
-    // TODO In the major version
-    // hexadecimalEscape: "lowercase" as const,
-    // controlEscape: "uppercase" as const,
-    hexadecimalEscape: "ignore" as const,
-    controlEscape: "ignore" as const,
+    hexadecimalEscape: "lowercase" as const,
+    controlEscape: "uppercase" as const,
 }
 
 /** Parse option */
diff --git a/lib/rules/match-any.ts b/lib/rules/match-any.ts
index f362dfe..9a312af 100644
--- a/lib/rules/match-any.ts
+++ b/lib/rules/match-any.ts
@@ -5,6 +5,7 @@ import type { RegExpContext } from "../utils"
 import { createRule, defineRegexpVisitor } from "../utils"
 import { isRegexpLiteral } from "../utils/ast-utils/utils"
 import { matchesAllCharacters } from "regexp-ast-analysis"
+import { mention } from "../utils/mention"
 
 const OPTION_SS1 = "[\\s\\S]" as const
 const OPTION_SS2 = "[\\S\\s]" as const
@@ -47,7 +48,7 @@ export default createRule("match-any", {
             },
         ],
         messages: {
-            unexpected: "Unexpected using '{{expr}}' to match any character.",
+            unexpected: "Unexpected using {{expr}} to match any character.",
         },
         type: "suggestion", // "problem",
     },
@@ -145,7 +146,7 @@ export default createRule("match-any", {
                             loc: getRegexpLocation(csNode),
                             messageId: "unexpected",
                             data: {
-                                expr: ".",
+                                expr: mention(csNode),
                             },
                             fix(fixer) {
                                 return fix(fixer, regexpContext, csNode)
@@ -163,7 +164,7 @@ export default createRule("match-any", {
                             loc: getRegexpLocation(ccNode),
                             messageId: "unexpected",
                             data: {
-                                expr: ccNode.raw,
+                                expr: mention(ccNode),
                             },
                             fix(fixer) {
                                 return fix(fixer, regexpContext, ccNode)
diff --git a/lib/rules/negation.ts b/lib/rules/negation.ts
index d1e616c..7a78a6a 100644
--- a/lib/rules/negation.ts
+++ b/lib/rules/negation.ts
@@ -11,9 +11,7 @@ export default createRule("negation", {
         docs: {
             description: "enforce use of escapes on negation",
             category: "Best Practices",
-            // TODO In the major version
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
diff --git a/lib/rules/no-dupe-disjunctions.ts b/lib/rules/no-dupe-disjunctions.ts
index 5a35477..b10f690 100644
--- a/lib/rules/no-dupe-disjunctions.ts
+++ b/lib/rules/no-dupe-disjunctions.ts
@@ -30,6 +30,7 @@ import {
 import { RegExpParser } from "regexpp"
 import { UsageOfPattern } from "../utils/get-usage-of-pattern"
 import { canReorder } from "../utils/reorder-alternatives"
+import { mention } from "../utils/mention"
 
 type ParentNode = Group | CapturingGroup | Pattern | LookaroundAssertion
 
@@ -688,9 +689,7 @@ export default createRule("no-dupe-disjunctions", {
         docs: {
             description: "disallow duplicate disjunctions",
             category: "Possible Errors",
-            // TODO In the major version
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         schema: [
             {
@@ -714,13 +713,13 @@ export default createRule("no-dupe-disjunctions", {
             duplicate:
                 "Unexpected duplicate alternative. This alternative can be removed.{{cap}}{{exp}}",
             subset:
-                "Unexpected useless alternative. This alternative is a strict subset of '{{others}}' and can be removed.{{cap}}{{exp}}",
+                "Unexpected useless alternative. This alternative is a strict subset of {{others}} and can be removed.{{cap}}{{exp}}",
             prefixSubset:
-                "Unexpected useless alternative. This alternative is already covered by '{{others}}' and can be removed.{{cap}}",
+                "Unexpected useless alternative. This alternative is already covered by {{others}} and can be removed.{{cap}}",
             superset:
-                "Unexpected superset. This alternative is a superset of '{{others}}'. It might be possible to remove the other alternative(s).{{cap}}{{exp}}",
+                "Unexpected superset. This alternative is a superset of {{others}}. It might be possible to remove the other alternative(s).{{cap}}{{exp}}",
             overlap:
-                "Unexpected overlap. This alternative overlaps with '{{others}}'. The overlap is '{{expr}}'.{{cap}}{{exp}}",
+                "Unexpected overlap. This alternative overlaps with {{others}}. The overlap is {{expr}}.{{cap}}{{exp}}",
         },
         type: "suggestion", // "problem",
     },
@@ -936,7 +935,9 @@ export default createRule("no-dupe-disjunctions", {
                     ? " Careful! This alternative contains capturing groups which might be difficult to remove."
                     : ""
 
-                const others = result.others.map((a) => a.raw).join("|")
+                const others = mention(
+                    result.others.map((a) => a.raw).join("|"),
+                )
 
                 switch (result.type) {
                     case "Duplicate":
@@ -984,7 +985,9 @@ export default createRule("no-dupe-disjunctions", {
                                 exp,
                                 cap,
                                 others,
-                                expr: faToSource(result.overlap, flags),
+                                expr: mention(
+                                    faToSource(result.overlap, flags),
+                                ),
                             },
                         })
                         break
diff --git a/lib/rules/no-empty-alternative.ts b/lib/rules/no-empty-alternative.ts
index 2aff2bc..93f10e2 100644
--- a/lib/rules/no-empty-alternative.ts
+++ b/lib/rules/no-empty-alternative.ts
@@ -8,9 +8,7 @@ export default createRule("no-empty-alternative", {
         docs: {
             description: "disallow alternatives without elements",
             category: "Possible Errors",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
             default: "warn",
         },
         schema: [],
diff --git a/lib/rules/no-empty-capturing-group.ts b/lib/rules/no-empty-capturing-group.ts
index a9913da..d296c4f 100644
--- a/lib/rules/no-empty-capturing-group.ts
+++ b/lib/rules/no-empty-capturing-group.ts
@@ -8,9 +8,7 @@ export default createRule("no-empty-capturing-group", {
         docs: {
             description: "disallow capturing group that captures empty.",
             category: "Possible Errors",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         schema: [],
         messages: {
diff --git a/lib/rules/no-invalid-regexp.ts b/lib/rules/no-invalid-regexp.ts
index 2820b0c..0c76ba2 100644
--- a/lib/rules/no-invalid-regexp.ts
+++ b/lib/rules/no-invalid-regexp.ts
@@ -17,10 +17,7 @@ export default createRule("no-invalid-regexp", {
             description:
                 "disallow invalid regular expression strings in `RegExp` constructors",
             category: "Possible Errors",
-            // TODO Switch to recommended in the major version.
-            // TODO When setting `recommended: true`, do not forget to disable ESLint's no-invalid-regexp in recommended.ts
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         schema: [],
         messages: {
diff --git a/lib/rules/no-lazy-ends.ts b/lib/rules/no-lazy-ends.ts
index cd8c9b7..5526962 100644
--- a/lib/rules/no-lazy-ends.ts
+++ b/lib/rules/no-lazy-ends.ts
@@ -48,9 +48,7 @@ export default createRule("no-lazy-ends", {
             description:
                 "disallow lazy quantifiers at the end of an expression",
             category: "Possible Errors",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
             default: "warn",
         },
         schema: [
diff --git a/lib/rules/no-legacy-features.ts b/lib/rules/no-legacy-features.ts
index 05d1f18..625c202 100644
--- a/lib/rules/no-legacy-features.ts
+++ b/lib/rules/no-legacy-features.ts
@@ -54,9 +54,7 @@ export default createRule("no-legacy-features", {
         docs: {
             description: "disallow legacy RegExp features",
             category: "Best Practices",
-            // TODO In the major version
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         schema: [
             {
diff --git a/lib/rules/no-non-standard-flag.ts b/lib/rules/no-non-standard-flag.ts
index 4b87958..6db73a9 100644
--- a/lib/rules/no-non-standard-flag.ts
+++ b/lib/rules/no-non-standard-flag.ts
@@ -8,9 +8,7 @@ export default createRule("no-non-standard-flag", {
         docs: {
             description: "disallow non-standard flags",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         schema: [],
         messages: {
diff --git a/lib/rules/no-obscure-range.ts b/lib/rules/no-obscure-range.ts
index 5385b03..87f2de3 100644
--- a/lib/rules/no-obscure-range.ts
+++ b/lib/rules/no-obscure-range.ts
@@ -20,9 +20,7 @@ export default createRule("no-obscure-range", {
         docs: {
             description: "disallow obscure character ranges",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         schema: [
             {
diff --git a/lib/rules/no-octal.ts b/lib/rules/no-octal.ts
index c2992a9..46df165 100644
--- a/lib/rules/no-octal.ts
+++ b/lib/rules/no-octal.ts
@@ -7,7 +7,7 @@ export default createRule("no-octal", {
         docs: {
             description: "disallow octal escape sequence",
             category: "Best Practices",
-            recommended: true,
+            recommended: false, //  `regexp/strict` rule meets this rule.
         },
         schema: [],
         messages: {
diff --git a/lib/rules/no-optional-assertion.ts b/lib/rules/no-optional-assertion.ts
index 482518c..fb1e610 100644
--- a/lib/rules/no-optional-assertion.ts
+++ b/lib/rules/no-optional-assertion.ts
@@ -72,9 +72,7 @@ export default createRule("no-optional-assertion", {
         docs: {
             description: "disallow optional assertions",
             category: "Possible Errors",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         schema: [],
         messages: {
diff --git a/lib/rules/no-potentially-useless-backreference.ts b/lib/rules/no-potentially-useless-backreference.ts
index 7f735ef..a3227ff 100644
--- a/lib/rules/no-potentially-useless-backreference.ts
+++ b/lib/rules/no-potentially-useless-backreference.ts
@@ -12,9 +12,7 @@ export default createRule("no-potentially-useless-backreference", {
             description:
                 "disallow backreferences that reference a group that might not be matched",
             category: "Possible Errors",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
             default: "warn",
         },
         schema: [],
diff --git a/lib/rules/no-standalone-backslash.ts b/lib/rules/no-standalone-backslash.ts
index 5cfb461..e3cb64c 100644
--- a/lib/rules/no-standalone-backslash.ts
+++ b/lib/rules/no-standalone-backslash.ts
@@ -7,9 +7,7 @@ export default createRule("no-standalone-backslash", {
         docs: {
             description: "disallow standalone backslashes (`\\`)",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: false, //  `regexp/strict` rule meets this rule.
         },
         schema: [],
         messages: {
diff --git a/lib/rules/no-super-linear-backtracking.ts b/lib/rules/no-super-linear-backtracking.ts
index b2d655c..4289fd2 100644
--- a/lib/rules/no-super-linear-backtracking.ts
+++ b/lib/rules/no-super-linear-backtracking.ts
@@ -5,6 +5,7 @@ import { UsageOfPattern } from "../utils/get-usage-of-pattern"
 import type { ParsedLiteral } from "scslre"
 import { analyse } from "scslre"
 import type { Position, SourceLocation } from "estree"
+import { mention } from "../utils/mention"
 
 /**
  * Returns the combined source location of the two given locations.
@@ -56,9 +57,7 @@ export default createRule("no-super-linear-backtracking", {
         docs: {
             description: "disallow exponential and polynomial backtracking",
             category: "Possible Errors",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [
@@ -74,11 +73,11 @@ export default createRule("no-super-linear-backtracking", {
         ],
         messages: {
             self:
-                "This quantifier can reach itself via the loop '{{parent}}'." +
+                "This quantifier can reach itself via the loop {{parent}}." +
                 " Using any string accepted by {{attack}}, this can be exploited to cause at least polynomial backtracking." +
                 "{{exp}}",
             trade:
-                "The quantifier '{{start}}' can exchange characters with '{{end}}'." +
+                "The quantifier {{start}} can exchange characters with {{end}}." +
                 " Using any string accepted by {{attack}}, this can be exploited to cause at least polynomial backtracking." +
                 "{{exp}}",
         },
@@ -134,7 +133,7 @@ export default createRule("no-super-linear-backtracking", {
                         data: {
                             exp,
                             attack,
-                            parent: report.parentQuant.raw,
+                            parent: mention(report.parentQuant),
                         },
                         fix,
                     })
@@ -149,8 +148,8 @@ export default createRule("no-super-linear-backtracking", {
                         data: {
                             exp,
                             attack,
-                            start: report.startQuant.raw,
-                            end: report.endQuant.raw,
+                            start: mention(report.startQuant),
+                            end: mention(report.endQuant),
                         },
                         fix,
                     })
diff --git a/lib/rules/no-trivially-nested-assertion.ts b/lib/rules/no-trivially-nested-assertion.ts
index 9683941..14d2d97 100644
--- a/lib/rules/no-trivially-nested-assertion.ts
+++ b/lib/rules/no-trivially-nested-assertion.ts
@@ -58,9 +58,7 @@ export default createRule("no-trivially-nested-assertion", {
         docs: {
             description: "disallow trivially nested assertions",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
diff --git a/lib/rules/no-trivially-nested-quantifier.ts b/lib/rules/no-trivially-nested-quantifier.ts
index 9e3e4d1..74ed7d2 100644
--- a/lib/rules/no-trivially-nested-quantifier.ts
+++ b/lib/rules/no-trivially-nested-quantifier.ts
@@ -141,9 +141,7 @@ export default createRule("no-trivially-nested-quantifier", {
             description:
                 "disallow nested quantifiers that can be rewritten as one quantifier",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
diff --git a/lib/rules/no-unused-capturing-group.ts b/lib/rules/no-unused-capturing-group.ts
index 927b392..1e083f6 100644
--- a/lib/rules/no-unused-capturing-group.ts
+++ b/lib/rules/no-unused-capturing-group.ts
@@ -173,7 +173,7 @@ export default createRule("no-unused-capturing-group", {
         docs: {
             description: "disallow unused capturing group",
             category: "Best Practices",
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [
diff --git a/lib/rules/no-useless-assertions.ts b/lib/rules/no-useless-assertions.ts
index df813d0..0418f7f 100644
--- a/lib/rules/no-useless-assertions.ts
+++ b/lib/rules/no-useless-assertions.ts
@@ -16,26 +16,27 @@ import {
     hasSomeDescendant,
     isPotentiallyEmpty,
 } from "regexp-ast-analysis"
+import { mention } from "../utils/mention"
 
 const messages = {
     alwaysRejectByChar:
-        "'{{assertion}}' will always reject because it is {{followedOrPreceded}} by a character.",
+        "{{assertion}} will always reject because it is {{followedOrPreceded}} by a character.",
     alwaysRejectByNonLineTerminator:
-        "'{{assertion}}' will always reject because it is {{followedOrPreceded}} by a non-line-terminator character.",
+        "{{assertion}} will always reject because it is {{followedOrPreceded}} by a non-line-terminator character.",
     alwaysAcceptByLineTerminator:
-        "'{{assertion}}' will always accept because it is {{followedOrPreceded}} by a line-terminator character.",
+        "{{assertion}} will always accept because it is {{followedOrPreceded}} by a line-terminator character.",
     alwaysAcceptOrRejectFollowedByWord:
-        "'{{assertion}}' will always {{acceptOrReject}} because it is preceded by a non-word character and followed by a word character.",
+        "{{assertion}} will always {{acceptOrReject}} because it is preceded by a non-word character and followed by a word character.",
     alwaysAcceptOrRejectFollowedByNonWord:
-        "'{{assertion}}' will always {{acceptOrReject}} because it is preceded by a non-word character and followed by a non-word character.",
+        "{{assertion}} will always {{acceptOrReject}} because it is preceded by a non-word character and followed by a non-word character.",
     alwaysAcceptOrRejectPrecededByWordFollowedByNonWord:
-        "'{{assertion}}' will always {{acceptOrReject}} because it is preceded by a word character and followed by a non-word character.",
+        "{{assertion}} will always {{acceptOrReject}} because it is preceded by a word character and followed by a non-word character.",
     alwaysAcceptOrRejectPrecededByWordFollowedByWord:
-        "'{{assertion}}' will always {{acceptOrReject}} because it is preceded by a word character and followed by a word character.",
+        "{{assertion}} will always {{acceptOrReject}} because it is preceded by a word character and followed by a word character.",
     alwaysForLookaround:
-        "The {{kind}} '{{assertion}}' will always {{acceptOrReject}}.",
+        "The {{kind}} {{assertion}} will always {{acceptOrReject}}.",
     alwaysForNegativeLookaround:
-        "The negative {{kind}} '{{assertion}}' will always {{acceptOrReject}}.",
+        "The negative {{kind}} {{assertion}} will always {{acceptOrReject}}.",
 }
 
 export default createRule("no-useless-assertions", {
@@ -44,9 +45,7 @@ export default createRule("no-useless-assertions", {
             description:
                 "disallow assertions that are known to always accept (or reject)",
             category: "Possible Errors",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         schema: [],
         messages,
@@ -72,7 +71,7 @@ export default createRule("no-useless-assertions", {
                     loc: getRegexpLocation(assertion),
                     messageId,
                     data: {
-                        assertion: assertion.raw,
+                        assertion: mention(assertion),
                         ...data,
                     },
                 })
diff --git a/lib/rules/no-useless-backreference.ts b/lib/rules/no-useless-backreference.ts
index 2ca89bc..84f5f3f 100644
--- a/lib/rules/no-useless-backreference.ts
+++ b/lib/rules/no-useless-backreference.ts
@@ -12,6 +12,7 @@ import {
     getMatchingDirection,
     isZeroLength,
 } from "regexp-ast-analysis"
+import { mention } from "../utils/mention"
 
 /**
  * Returns whether the list of ancestors from `from` to `to` contains a negated
@@ -89,17 +90,17 @@ export default createRule("no-useless-backreference", {
         schema: [],
         messages: {
             nested:
-                "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' from within that group.",
+                "Backreference {{ bref }} will be ignored. It references group {{ group }} from within that group.",
             forward:
-                "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which appears later in the pattern.",
+                "Backreference {{ bref }} will be ignored. It references group {{ group }} which appears later in the pattern.",
             backward:
-                "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which appears before in the same lookbehind.",
+                "Backreference {{ bref }} will be ignored. It references group {{ group }} which appears before in the same lookbehind.",
             disjunctive:
-                "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which is in another alternative.",
+                "Backreference {{ bref }} will be ignored. It references group {{ group }} which is in another alternative.",
             intoNegativeLookaround:
-                "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which is in a negative lookaround.",
+                "Backreference {{ bref }} will be ignored. It references group {{ group }} which is in a negative lookaround.",
             empty:
-                "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which always captures zero characters.",
+                "Backreference {{ bref }} will be ignored. It references group {{ group }} which always captures zero characters.",
         },
         type: "suggestion", // "problem",
     },
@@ -121,8 +122,8 @@ export default createRule("no-useless-backreference", {
                             loc: getRegexpLocation(backRef),
                             messageId,
                             data: {
-                                bref: backRef.raw,
-                                group: backRef.resolved.raw,
+                                bref: mention(backRef),
+                                group: mention(backRef.resolved),
                             },
                         })
                     }
diff --git a/lib/rules/no-useless-character-class.ts b/lib/rules/no-useless-character-class.ts
index 521dd46..4a647f9 100644
--- a/lib/rules/no-useless-character-class.ts
+++ b/lib/rules/no-useless-character-class.ts
@@ -7,9 +7,7 @@ export default createRule("no-useless-character-class", {
         docs: {
             description: "disallow character class with one character",
             category: "Best Practices",
-            // TODO In the major version
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [
diff --git a/lib/rules/no-useless-dollar-replacements.ts b/lib/rules/no-useless-dollar-replacements.ts
index a4bdbf4..2c79fce 100644
--- a/lib/rules/no-useless-dollar-replacements.ts
+++ b/lib/rules/no-useless-dollar-replacements.ts
@@ -25,7 +25,7 @@ export default createRule("no-useless-dollar-replacements", {
             description:
                 "disallow useless `$` replacements in replacement string",
             category: "Possible Errors",
-            recommended: false,
+            recommended: true,
         },
         schema: [],
         messages: {
diff --git a/lib/rules/no-useless-escape.ts b/lib/rules/no-useless-escape.ts
index 55d7892..00d644a 100644
--- a/lib/rules/no-useless-escape.ts
+++ b/lib/rules/no-useless-escape.ts
@@ -53,9 +53,7 @@ export default createRule("no-useless-escape", {
         docs: {
             description: "disallow unnecessary escape characters in RegExp",
             category: "Stylistic Issues",
-            // TODO In the major version
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
diff --git a/lib/rules/no-useless-flag.ts b/lib/rules/no-useless-flag.ts
index 55c508d..16a6e9e 100644
--- a/lib/rules/no-useless-flag.ts
+++ b/lib/rules/no-useless-flag.ts
@@ -805,9 +805,7 @@ export default createRule("no-useless-flag", {
         docs: {
             description: "disallow unnecessary regex flags",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
             default: "warn",
         },
         fixable: "code",
diff --git a/lib/rules/no-useless-lazy.ts b/lib/rules/no-useless-lazy.ts
index 0459baf..1987a67 100644
--- a/lib/rules/no-useless-lazy.ts
+++ b/lib/rules/no-useless-lazy.ts
@@ -46,9 +46,7 @@ export default createRule("no-useless-lazy", {
         docs: {
             description: "disallow unnecessarily non-greedy quantifiers",
             category: "Best Practices",
-            // TODO In the major version
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
@@ -94,7 +92,7 @@ export default createRule("no-useless-lazy", {
 
                     const matchingDir = getMatchingDirection(qNode)
                     const firstChar = getFirstConsumedChar(
-                        qNode,
+                        qNode.element,
                         matchingDir,
                         flags,
                     )
diff --git a/lib/rules/no-useless-non-capturing-group.ts b/lib/rules/no-useless-non-capturing-group.ts
index bf432c6..fe81b49 100644
--- a/lib/rules/no-useless-non-capturing-group.ts
+++ b/lib/rules/no-useless-non-capturing-group.ts
@@ -28,9 +28,7 @@ export default createRule("no-useless-non-capturing-group", {
         docs: {
             description: "disallow unnecessary Non-capturing group",
             category: "Stylistic Issues",
-            // TODO In the major version
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [
diff --git a/lib/rules/no-useless-quantifier.ts b/lib/rules/no-useless-quantifier.ts
index 780a7ca..9345ac3 100644
--- a/lib/rules/no-useless-quantifier.ts
+++ b/lib/rules/no-useless-quantifier.ts
@@ -10,9 +10,7 @@ export default createRule("no-useless-quantifier", {
         docs: {
             description: "disallow quantifiers that can be removed",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
diff --git a/lib/rules/no-useless-range.ts b/lib/rules/no-useless-range.ts
index 805717d..84f26a3 100644
--- a/lib/rules/no-useless-range.ts
+++ b/lib/rules/no-useless-range.ts
@@ -8,8 +8,7 @@ export default createRule("no-useless-range", {
             description:
                 "disallow unnecessary range of characters by using a hyphen",
             category: "Best Practices",
-            // TODO In the major version, it will be changed to "recommended".
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
diff --git a/lib/rules/no-zero-quantifier.ts b/lib/rules/no-zero-quantifier.ts
index 4a716aa..e44cb7a 100644
--- a/lib/rules/no-zero-quantifier.ts
+++ b/lib/rules/no-zero-quantifier.ts
@@ -9,9 +9,7 @@ export default createRule("no-zero-quantifier", {
         docs: {
             description: "disallow quantifiers with a maximum of zero",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         schema: [],
         messages: {
diff --git a/lib/rules/optimal-lookaround-quantifier.ts b/lib/rules/optimal-lookaround-quantifier.ts
index 3291357..cdbacf4 100644
--- a/lib/rules/optimal-lookaround-quantifier.ts
+++ b/lib/rules/optimal-lookaround-quantifier.ts
@@ -3,6 +3,7 @@ import type { Alternative, LookaroundAssertion, Quantifier } from "regexpp/ast"
 import type { RegExpContext } from "../utils"
 import { createRule, defineRegexpVisitor } from "../utils"
 import { hasSomeDescendant } from "regexp-ast-analysis"
+import { mention } from "../utils/mention"
 
 /**
  * Extract invalid quantifiers for lookarounds
@@ -57,17 +58,15 @@ export default createRule("optimal-lookaround-quantifier", {
             description:
                 "disallow the alternatives of lookarounds that end with a non-constant quantifier",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
             default: "warn",
         },
         schema: [],
         messages: {
             remove:
-                "The quantified expression '{{expr}}' at the {{endOrStart}} of the expression tree should only be matched a constant number of times. The expression can be removed without affecting the lookaround.",
+                "The quantified expression {{expr}} at the {{endOrStart}} of the expression tree should only be matched a constant number of times. The expression can be removed without affecting the lookaround.",
             replacedWith:
-                "The quantified expression '{{expr}}' at the {{endOrStart}} of the expression tree should only be matched a constant number of times. The expression can be replaced with {{replacer}} without affecting the lookaround.",
+                "The quantified expression {{expr}} at the {{endOrStart}} of the expression tree should only be matched a constant number of times. The expression can be replaced with {{replacer}} without affecting the lookaround.",
         },
         type: "problem",
     },
@@ -105,7 +104,7 @@ export default createRule("optimal-lookaround-quantifier", {
                                 messageId:
                                     q.min === 0 ? "remove" : "replacedWith",
                                 data: {
-                                    expr: q.raw,
+                                    expr: mention(q),
                                     endOrStart,
                                     replacer,
                                 },
diff --git a/lib/rules/optimal-quantifier-concatenation.ts b/lib/rules/optimal-quantifier-concatenation.ts
index e4c30fc..19f853c 100644
--- a/lib/rules/optimal-quantifier-concatenation.ts
+++ b/lib/rules/optimal-quantifier-concatenation.ts
@@ -19,6 +19,7 @@ import { createRule, defineRegexpVisitor, quantToString } from "../utils"
 import { Chars, hasSomeDescendant } from "regexp-ast-analysis"
 import { getPossiblyConsumedChar } from "../utils/regexp-ast"
 import type { CharSet } from "refa"
+import { mention } from "../utils/mention"
 
 /**
  * Returns whether the given node is or contains a capturing group.
@@ -503,25 +504,23 @@ export default createRule("optimal-quantifier-concatenation", {
             description:
                 "require optimal quantifiers for concatenated quantifiers",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
         messages: {
             combine:
-                "'{{left}}' and '{{right}}' can be combined into one quantifier '{{fix}}'.{{cap}}",
+                "{{left}} and {{right}} can be combined into one quantifier {{fix}}.{{cap}}",
             removeLeft:
-                "'{{left}}' can be removed because it is already included by '{{right}}'.{{cap}}",
+                "{{left}} can be removed because it is already included by {{right}}.{{cap}}",
             removeRight:
-                "'{{right}}' can be removed because it is already included by '{{left}}'.{{cap}}",
+                "{{right}} can be removed because it is already included by {{left}}.{{cap}}",
             replace:
-                "'{{left}}' and '{{right}}' can be replaced with '{{fix}}'.{{cap}}",
+                "{{left}} and {{right}} can be replaced with {{fix}}.{{cap}}",
             nestedRemove:
-                "'{{nested}}' can be removed because of '{{dominate}}'.{{cap}}",
+                "{{nested}} can be removed because of {{dominate}}.{{cap}}",
             nestedReplace:
-                "'{{nested}}' can be replaced with '{{fix}}' because of '{{dominate}}'.{{cap}}",
+                "{{nested}} can be replaced with {{fix}} because of {{dominate}}.{{cap}}",
         },
         type: "suggestion",
     },
@@ -562,9 +561,9 @@ export default createRule("optimal-quantifier-concatenation", {
                                 loc: getLoc(left, right, regexpContext),
                                 messageId: replacement.messageId,
                                 data: {
-                                    left: left.raw,
-                                    right: right.raw,
-                                    fix: replacement.raw,
+                                    left: mention(left),
+                                    right: mention(right),
+                                    fix: mention(replacement.raw),
                                     cap,
                                 },
                                 fix: fixReplaceNode(aNode, () => {
@@ -589,9 +588,9 @@ export default createRule("optimal-quantifier-concatenation", {
                                 loc: getRegexpLocation(replacement.nested),
                                 messageId: replacement.messageId,
                                 data: {
-                                    nested: replacement.nested.raw,
-                                    dominate: replacement.dominate.raw,
-                                    fix: replacement.raw,
+                                    nested: mention(replacement.nested),
+                                    dominate: mention(replacement.dominate),
+                                    fix: mention(replacement.raw),
                                     cap,
                                 },
                                 fix: fixReplaceNode(replacement.nested, () => {
diff --git a/lib/rules/prefer-character-class.ts b/lib/rules/prefer-character-class.ts
index 5102c2e..fd36bf5 100644
--- a/lib/rules/prefer-character-class.ts
+++ b/lib/rules/prefer-character-class.ts
@@ -416,9 +416,7 @@ export default createRule("prefer-character-class", {
         docs: {
             description: "enforce using character class",
             category: "Stylistic Issues",
-            // TODO In the major version
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
diff --git a/lib/rules/prefer-d.ts b/lib/rules/prefer-d.ts
index 59e83a9..b045c4e 100644
--- a/lib/rules/prefer-d.ts
+++ b/lib/rules/prefer-d.ts
@@ -7,6 +7,7 @@ import {
     CP_DIGIT_NINE,
 } from "../utils"
 import { Chars } from "regexp-ast-analysis"
+import { mention } from "../utils/mention"
 
 export default createRule("prefer-d", {
     meta: {
@@ -19,7 +20,7 @@ export default createRule("prefer-d", {
         schema: [],
         messages: {
             unexpected:
-                "Unexpected {{type}} '{{expr}}'. Use '{{instead}}' instead.",
+                "Unexpected {{type}} {{expr}}. Use '{{instead}}' instead.",
         },
         type: "suggestion", // "problem",
     },
@@ -56,7 +57,7 @@ export default createRule("prefer-d", {
                             messageId: "unexpected",
                             data: {
                                 type: "character class",
-                                expr: ccNode.raw,
+                                expr: mention(ccNode),
                                 instead: predefined,
                             },
                             fix: fixReplaceNode(ccNode, predefined),
@@ -83,7 +84,7 @@ export default createRule("prefer-d", {
                             messageId: "unexpected",
                             data: {
                                 type: "character class range",
-                                expr: ccrNode.raw,
+                                expr: mention(ccrNode),
                                 instead,
                             },
                             fix: fixReplaceNode(ccrNode, instead),
diff --git a/lib/rules/prefer-predefined-assertion.ts b/lib/rules/prefer-predefined-assertion.ts
index ad9d823..c574e9b 100644
--- a/lib/rules/prefer-predefined-assertion.ts
+++ b/lib/rules/prefer-predefined-assertion.ts
@@ -41,9 +41,7 @@ export default createRule("prefer-predefined-assertion", {
             description:
                 "prefer predefined assertion over equivalent lookarounds",
             category: "Best Practices",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
diff --git a/lib/rules/prefer-question-quantifier.ts b/lib/rules/prefer-question-quantifier.ts
index 7c3dbce..0be48d4 100644
--- a/lib/rules/prefer-question-quantifier.ts
+++ b/lib/rules/prefer-question-quantifier.ts
@@ -1,3 +1,4 @@
+import { mention } from "../utils/mention"
 import type { Group, Quantifier } from "regexpp/ast"
 import type { RegExpVisitor } from "regexpp/visitor"
 import type { RegExpContext } from "../utils"
@@ -15,7 +16,7 @@ export default createRule("prefer-question-quantifier", {
         messages: {
             unexpected: "Unexpected quantifier '{{expr}}'. Use '?' instead.",
             unexpectedGroup:
-                "Unexpected group '{{expr}}'. Use '{{instead}}' instead.",
+                "Unexpected group {{expr}}. Use '{{instead}}' instead.",
         },
         type: "suggestion", // "problem",
     },
@@ -96,7 +97,7 @@ export default createRule("prefer-question-quantifier", {
                             loc: getRegexpLocation(reportNode),
                             messageId: "unexpectedGroup",
                             data: {
-                                expr: reportNode.raw,
+                                expr: mention(reportNode),
                                 instead,
                             },
                             fix: fixReplaceNode(reportNode, instead),
diff --git a/lib/rules/prefer-range.ts b/lib/rules/prefer-range.ts
index c9cae54..6cdf155 100644
--- a/lib/rules/prefer-range.ts
+++ b/lib/rules/prefer-range.ts
@@ -8,15 +8,14 @@ import {
     inRange,
 } from "../utils/char-ranges"
 import type { PatternReplaceRange } from "../utils/ast-utils/pattern-source"
+import { mention } from "../utils/mention"
 
 export default createRule("prefer-range", {
     meta: {
         docs: {
             description: "enforce using character class range",
             category: "Best Practices",
-            // TODO In the major version
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [
@@ -30,7 +29,7 @@ export default createRule("prefer-range", {
         ],
         messages: {
             unexpected:
-                "Unexpected multiple adjacent characters. Use '{{range}}' instead.",
+                "Unexpected multiple adjacent characters. Use {{range}} instead.",
         },
         type: "suggestion", // "problem",
     },
@@ -161,7 +160,7 @@ export default createRule("prefer-range", {
                                     node,
                                     loc: node.loc!,
                                     messageId: "unexpected",
-                                    data: { range: newText },
+                                    data: { range: mention(newText) },
                                 })
                                 continue
                             }
@@ -171,7 +170,7 @@ export default createRule("prefer-range", {
                                     node,
                                     loc: range.getAstLocation(sourceCode),
                                     messageId: "unexpected",
-                                    data: { range: newText },
+                                    data: { range: mention(newText) },
                                     fix: (fixer) => {
                                         return ranges.map((r, index) => {
                                             if (index === 0) {
diff --git a/lib/rules/prefer-t.ts b/lib/rules/prefer-t.ts
index a91fce8..171ec5d 100644
--- a/lib/rules/prefer-t.ts
+++ b/lib/rules/prefer-t.ts
@@ -1,3 +1,4 @@
+import { mention } from "../utils/mention"
 import type { RegExpVisitor } from "regexpp/visitor"
 import type { RegExpContext } from "../utils"
 import { createRule, defineRegexpVisitor, CP_TAB } from "../utils"
@@ -13,7 +14,7 @@ export default createRule("prefer-t", {
         fixable: "code",
         schema: [],
         messages: {
-            unexpected: "Unexpected character '{{expr}}'. Use '\\t' instead.",
+            unexpected: "Unexpected character {{expr}}. Use '\\t' instead.",
         },
         type: "suggestion", // "problem",
         deprecated: true,
@@ -39,7 +40,7 @@ export default createRule("prefer-t", {
                             loc: getRegexpLocation(cNode),
                             messageId: "unexpected",
                             data: {
-                                expr: cNode.raw,
+                                expr: mention(cNode),
                             },
                             fix: fixReplaceNode(cNode, "\\t"),
                         })
diff --git a/lib/rules/prefer-unicode-codepoint-escapes.ts b/lib/rules/prefer-unicode-codepoint-escapes.ts
index 6a9d5ee..2bb31ab 100644
--- a/lib/rules/prefer-unicode-codepoint-escapes.ts
+++ b/lib/rules/prefer-unicode-codepoint-escapes.ts
@@ -7,8 +7,7 @@ export default createRule("prefer-unicode-codepoint-escapes", {
         docs: {
             description: "enforce use of unicode codepoint escapes",
             category: "Stylistic Issues",
-            // TODO In the major version, it will be changed to "recommended".
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
diff --git a/lib/rules/prefer-w.ts b/lib/rules/prefer-w.ts
index 1c08c0b..db66e15 100644
--- a/lib/rules/prefer-w.ts
+++ b/lib/rules/prefer-w.ts
@@ -14,6 +14,7 @@ import {
     CP_LOW_LINE,
 } from "../utils"
 import { Chars } from "regexp-ast-analysis"
+import { mention } from "../utils/mention"
 
 /**
  * Checks if small letter char class range
@@ -71,7 +72,7 @@ export default createRule("prefer-w", {
         schema: [],
         messages: {
             unexpected:
-                "Unexpected {{type}} '{{expr}}'. Use '{{instead}}' instead.",
+                "Unexpected {{type}} {{expr}}. Use '{{instead}}' instead.",
         },
         type: "suggestion", // "problem",
     },
@@ -105,7 +106,7 @@ export default createRule("prefer-w", {
                             messageId: "unexpected",
                             data: {
                                 type: "character class",
-                                expr: ccNode.raw,
+                                expr: mention(ccNode),
                                 instead: predefined,
                             },
                             fix: fixReplaceNode(ccNode, predefined),
@@ -156,9 +157,9 @@ export default createRule("prefer-w", {
                             messageId: "unexpected",
                             data: {
                                 type: "character class ranges",
-                                expr: `[${unexpectedElements
+                                expr: `'[${unexpectedElements
                                     .map((e) => e.raw)
-                                    .join("")}]`,
+                                    .join("")}]'`,
                                 instead: "\\w",
                             },
                             fix(fixer: Rule.RuleFixer) {
diff --git a/lib/rules/sort-alternatives.ts b/lib/rules/sort-alternatives.ts
index 8e6111a..7989c43 100644
--- a/lib/rules/sort-alternatives.ts
+++ b/lib/rules/sort-alternatives.ts
@@ -3,6 +3,10 @@ import type { Alternative, Element, Pattern } from "regexpp/ast"
 import type { RegExpContext } from "../utils"
 import {
     CP_MINUS,
+    CP_PLUS,
+    CP_STAR,
+    CP_QUESTION,
+    CP_SLASH,
     CP_SPACE,
     CP_APOSTROPHE,
     createRule,
@@ -16,7 +20,6 @@ import {
 } from "regexp-ast-analysis"
 import type { CharSet } from "refa"
 import { JS } from "refa"
-import type { SourceLocation, Position } from "estree"
 import { canReorder } from "../utils/reorder-alternatives"
 import { getPossiblyConsumedChar } from "../utils/regexp-ast"
 
@@ -36,8 +39,15 @@ function getAllowedChars(flags: ReadonlyFlags) {
                 [
                     { kind: "word", negate: false },
                     { min: CP_SPACE, max: CP_SPACE },
+
+                    // common punctuation and operators
+                    { min: CP_PLUS, max: CP_PLUS },
                     { min: CP_MINUS, max: CP_MINUS },
+                    { min: CP_STAR, max: CP_STAR },
+                    { min: CP_SLASH, max: CP_SLASH },
+
                     { min: CP_APOSTROPHE, max: CP_APOSTROPHE },
+                    { min: CP_QUESTION, max: CP_QUESTION },
                 ],
                 flags,
             ),
@@ -133,50 +143,12 @@ function isIntegerString(str: string): boolean {
  * are a number.
  */
 function trySortNumberAlternatives(alternatives: Alternative[]): void {
-    const numberRanges: [number, number][] = []
-    {
-        let start = 0
-        for (let i = 0; i < alternatives.length; i++) {
-            if (!isIntegerString(alternatives[i].raw)) {
-                if (start < i) {
-                    numberRanges.push([start, i])
-                }
-                start = i + 1
-            }
-        }
-        if (start < alternatives.length) {
-            numberRanges.push([start, alternatives.length])
-        }
-    }
-
-    for (const [start, end] of numberRanges) {
-        const slice = alternatives.slice(start, end)
-
-        slice.sort((a, b) => {
+    const runs = getRuns(alternatives, (a) => isIntegerString(a.raw))
+    for (const { startIndex, elements } of runs) {
+        elements.sort((a, b) => {
             return Number(a.raw) - Number(b.raw)
         })
-
-        alternatives.splice(start, end - start, ...slice)
-    }
-}
-
-/**
- * Returns the combined source location of the two given locations.
- */
-function unionLocations(a: SourceLocation, b: SourceLocation): SourceLocation {
-    /** x < y */
-    function less(x: Position, y: Position): boolean {
-        if (x.line < y.line) {
-            return true
-        } else if (x.line > y.line) {
-            return false
-        }
-        return x.column < y.column
-    }
-
-    return {
-        start: { ...(less(a.start, b.start) ? a.start : b.start) },
-        end: { ...(less(a.end, b.end) ? b.end : a.end) },
+        alternatives.splice(startIndex, elements.length, ...elements)
     }
 }
 
@@ -208,7 +180,7 @@ function getReorderingBounds<T>(
 }
 
 interface Run<T> {
-    index: number
+    startIndex: number
     elements: T[]
 }
 
@@ -226,7 +198,7 @@ function getRuns<T>(iter: Iterable<T>, condFn: (item: T) => boolean): Run<T>[] {
             elements.push(item)
         } else {
             if (elements.length > 0) {
-                runs.push({ index, elements })
+                runs.push({ startIndex: index - elements.length, elements })
                 elements = []
             }
         }
@@ -234,6 +206,11 @@ function getRuns<T>(iter: Iterable<T>, condFn: (item: T) => boolean): Run<T>[] {
         index++
     }
 
+    if (elements.length > 0) {
+        runs.push({ startIndex: index - elements.length, elements })
+        elements = []
+    }
+
     return runs
 }
 
@@ -253,6 +230,8 @@ export default createRule("sort-alternatives", {
         type: "suggestion", // "problem",
     },
     create(context) {
+        const sliceMinLength = 3
+
         /**
          * Create visitor
          */
@@ -268,23 +247,76 @@ export default createRule("sort-alternatives", {
 
             const allowedChars = getAllowedChars(flags)
 
+            const possibleCharsCache = new Map<Alternative, CharSet>()
+
+            /** A cached version of getPossiblyConsumedChar */
+            function getPossibleChars(a: Alternative): CharSet {
+                let chars = possibleCharsCache.get(a)
+                if (chars === undefined) {
+                    chars = getPossiblyConsumedChar(a, regexpContext).char
+                    possibleCharsCache.set(a, chars)
+                }
+                return chars
+            }
+
+            /** Tries to sort the given alternatives. */
+            function trySortRun(run: Run<Alternative>): void {
+                const alternatives = run.elements
+
+                if (canReorder(alternatives, regexpContext)) {
+                    // alternatives can be reordered freely
+                    sortAlternatives(alternatives, regexpContext)
+                    trySortNumberAlternatives(alternatives)
+                } else {
+                    const consumedChars = Chars.empty(flags).union(
+                        ...alternatives.map(getPossibleChars),
+                    )
+                    if (!consumedChars.isDisjointWith(Chars.digit(flags))) {
+                        // let's try to at least sort numbers
+                        const runs = getRuns(alternatives, (a) =>
+                            isIntegerString(a.raw),
+                        )
+
+                        for (const { startIndex: index, elements } of runs) {
+                            if (
+                                elements.length > 1 &&
+                                canReorder(elements, regexpContext)
+                            ) {
+                                trySortNumberAlternatives(elements)
+                                alternatives.splice(
+                                    index,
+                                    elements.length,
+                                    ...elements,
+                                )
+                            }
+                        }
+                    }
+                }
+
+                enforceSorted(run)
+            }
+
             /**
              * Creates a report if the sorted alternatives are different from
              * the unsorted ones.
              */
-            function enforceSorted(sorted: Alternative[]): void {
+            function enforceSorted(run: Run<Alternative>): void {
+                const sorted = run.elements
                 const parent = sorted[0].parent
-                const unsorted = parent.alternatives
+                const unsorted = parent.alternatives.slice(
+                    run.startIndex,
+                    run.startIndex + sorted.length,
+                )
 
                 const bounds = getReorderingBounds(unsorted, sorted)
                 if (!bounds) {
                     return
                 }
 
-                const loc = unionLocations(
-                    getRegexpLocation(unsorted[bounds[0]]),
-                    getRegexpLocation(unsorted[bounds[1]]),
-                )
+                const loc = getRegexpLocation({
+                    start: unsorted[bounds[0]].start,
+                    end: unsorted[bounds[1]].end,
+                })
 
                 context.report({
                     node,
@@ -293,11 +325,10 @@ export default createRule("sort-alternatives", {
                     fix: fixReplaceNode(parent, () => {
                         const prefix = parent.raw.slice(
                             0,
-                            parent.alternatives[0].start - parent.start,
+                            unsorted[0].start - parent.start,
                         )
                         const suffix = parent.raw.slice(
-                            parent.alternatives[parent.alternatives.length - 1]
-                                .end - parent.start,
+                            unsorted[unsorted.length - 1].end - parent.start,
                         )
 
                         return (
@@ -313,65 +344,46 @@ export default createRule("sort-alternatives", {
                     return
                 }
 
-                if (!containsOnlyLiterals(parent)) {
-                    return
-                }
-
-                if (
-                    hasSomeDescendant(
-                        parent,
-                        (d) => d !== parent && d.type === "CapturingGroup",
-                    )
-                ) {
-                    // it's not safe to reorder alternatives with capturing groups
-                    return
-                }
+                const runs = getRuns(parent.alternatives, (a) => {
+                    if (!containsOnlyLiterals(a)) {
+                        return false
+                    }
 
-                const consumedChars = getPossiblyConsumedChar(
-                    parent,
-                    regexpContext,
-                ).char
-                if (consumedChars.isEmpty) {
-                    // all alternatives are either empty or only contain
-                    // assertions
-                    return
-                }
-                if (!consumedChars.isSubsetOf(allowedChars.allowed)) {
-                    // contains some chars that are not allowed
-                    return
-                }
-                if (consumedChars.isDisjointWith(allowedChars.required)) {
-                    // doesn't contain required chars
-                    return
-                }
+                    const consumedChars = getPossibleChars(a)
+                    if (consumedChars.isEmpty) {
+                        // the alternative is either empty or only contains
+                        // assertions
+                        return false
+                    }
+                    if (!consumedChars.isSubsetOf(allowedChars.allowed)) {
+                        // contains some chars that are not allowed
+                        return false
+                    }
+                    if (consumedChars.isDisjointWith(allowedChars.required)) {
+                        // doesn't contain required chars
+                        return false
+                    }
 
-                const alternatives = [...parent.alternatives]
+                    return true
+                })
 
-                if (canReorder(alternatives, regexpContext)) {
-                    // alternatives can be reordered freely
-                    sortAlternatives(alternatives, regexpContext)
-                    trySortNumberAlternatives(alternatives)
-                } else if (!consumedChars.isDisjointWith(Chars.digit(flags))) {
-                    // let's try to at least sort numbers
-                    const runs = getRuns(alternatives, (a) =>
-                        isIntegerString(a.raw),
-                    )
-                    for (const { index, elements } of runs) {
+                if (
+                    runs.length === 1 &&
+                    runs[0].elements.length === parent.alternatives.length
+                ) {
+                    // All alternatives are to be sorted
+                    trySortRun(runs[0])
+                } else {
+                    // Some slices are to be sorted
+                    for (const run of runs) {
                         if (
-                            elements.length > 1 &&
-                            canReorder(elements, regexpContext)
+                            run.elements.length >= sliceMinLength &&
+                            run.elements.length >= 2
                         ) {
-                            trySortNumberAlternatives(elements)
-                            alternatives.splice(
-                                index,
-                                elements.length,
-                                ...elements,
-                            )
+                            trySortRun(run)
                         }
                     }
                 }
-
-                enforceSorted(alternatives)
             }
 
             return {
diff --git a/lib/rules/sort-flags.ts b/lib/rules/sort-flags.ts
index 20f5969..a776a3e 100644
--- a/lib/rules/sort-flags.ts
+++ b/lib/rules/sort-flags.ts
@@ -6,9 +6,7 @@ export default createRule("sort-flags", {
         docs: {
             description: "require regex flags to be sorted",
             category: "Stylistic Issues",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
diff --git a/lib/rules/strict.ts b/lib/rules/strict.ts
index 5656ecd..3e23258 100644
--- a/lib/rules/strict.ts
+++ b/lib/rules/strict.ts
@@ -1,3 +1,4 @@
+import { mention } from "../utils/mention"
 import { RegExpValidator } from "regexpp"
 import type { CharacterClassElement, Element } from "regexpp/ast"
 import type { RegExpVisitor } from "regexpp/visitor"
@@ -35,9 +36,7 @@ export default createRule("strict", {
         docs: {
             description: "disallow not strictly valid regular expressions",
             category: "Possible Errors",
-            // TODO Switch to recommended in the major version.
-            // recommended: true,
-            recommended: false,
+            recommended: true,
         },
         fixable: "code",
         schema: [],
@@ -46,14 +45,14 @@ export default createRule("strict", {
             invalidControlEscape:
                 "Invalid or incomplete control escape sequence. Either use a valid control escape sequence or escaping the standalone backslash.",
             incompleteEscapeSequence:
-                "Incomplete escape sequence '{{expr}}'. Either use a valid escape sequence or remove the useless escaping.",
+                "Incomplete escape sequence {{expr}}. Either use a valid escape sequence or remove the useless escaping.",
             invalidPropertyEscape:
-                "Invalid property escape sequence '{{expr}}'. Either use a valid property escape sequence or remove the useless escaping.",
+                "Invalid property escape sequence {{expr}}. Either use a valid property escape sequence or remove the useless escaping.",
             incompleteBackreference:
-                "Incomplete backreference '{{expr}}'. Either use a valid backreference or remove the useless escaping.",
-            unescapedSourceCharacter: "Unescaped source character '{{expr}}'.",
+                "Incomplete backreference {{expr}}. Either use a valid backreference or remove the useless escaping.",
+            unescapedSourceCharacter: "Unescaped source character {{expr}}.",
             octalEscape:
-                "Invalid legacy octal escape sequence '{{expr}}'. Use a hexadecimal escape instead.",
+                "Invalid legacy octal escape sequence {{expr}}. Use a hexadecimal escape instead.",
             uselessEscape:
                 "Useless identity escapes with non-syntax characters are forbidden.",
 
@@ -111,7 +110,7 @@ export default createRule("strict", {
                         loc: getRegexpLocation(element),
                         messageId,
                         data: {
-                            expr: element.raw,
+                            expr: mention(element),
                         },
                         suggest: [
                             {
@@ -126,7 +125,7 @@ export default createRule("strict", {
                         loc: getRegexpLocation(element),
                         messageId,
                         data: {
-                            expr: element.raw,
+                            expr: mention(element),
                         },
                         fix: fix ? fixReplaceNode(element, fix) : null,
                     })
diff --git a/lib/utils/mention.ts b/lib/utils/mention.ts
index efa8da0..7b8f698 100644
--- a/lib/utils/mention.ts
+++ b/lib/utils/mention.ts
@@ -28,8 +28,8 @@ export function mentionChar(element: CharacterClassElement): string {
 /**
  * Creates a string that mentions the given character class element.
  */
-export function mention(element: Node): string {
-    return `'${escape(element.raw)}'`
+export function mention(element: Node | string): string {
+    return `'${escape(typeof element === "string" ? element : element.raw)}'`
 }
 
 /** Escape control characters in the given string */
diff --git a/package-lock.json b/package-lock.json
index a27ee46..8b8fd09 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13226,9 +13226,9 @@
             }
         },
         "regexp-ast-analysis": {
-            "version": "0.2.3",
-            "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.2.3.tgz",
-            "integrity": "sha512-K/6d90dP1DI68HHdHORj9vVxV5oWkLB8F7LeGs70EdA/h5BIqkrK8SdGy+O9Ii+AVVPprF0Ia6f5UwgI+ahIcw==",
+            "version": "0.2.4",
+            "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.2.4.tgz",
+            "integrity": "sha512-8L7kOZQaKPxKKAwGuUZxTQtlO3WZ+tiXy4s6G6PKL6trbOXcZoumwC3AOHHFtI/xoSbNxt7jgLvCnP1UADLWqg==",
             "requires": {
                 "refa": "^0.9.0",
                 "regexpp": "^3.2.0"
diff --git a/package.json b/package.json
index 4ee8279..1c34d55 100644
--- a/package.json
+++ b/package.json
@@ -95,7 +95,7 @@
         "eslint-utils": "^3.0.0",
         "jsdoctypeparser": "^9.0.0",
         "refa": "^0.9.0",
-        "regexp-ast-analysis": "^0.2.3",
+        "regexp-ast-analysis": "^0.2.4",
         "regexpp": "^3.2.0",
         "scslre": "^0.1.6"
     }
diff --git a/tools/update-rulesets.ts b/tools/update-rulesets.ts
index 78f2311..6114701 100644
--- a/tools/update-rulesets.ts
+++ b/tools/update-rulesets.ts
@@ -6,9 +6,7 @@ import { rules } from "./lib/load-rules"
 const coreRules = [
     // Possible Errors
     "no-control-regex",
-    // TODO In the major version
-    // "no-empty-character-class",
-    "no-invalid-regexp",
+    "no-empty-character-class",
     "no-misleading-character-class",
     "no-regex-spaces",
     // Best Practices
@@ -24,6 +22,7 @@ export = {
         // ESLint core rules
         ${coreRules.map((ruleName) => `"${ruleName}": "error"`).join(",\n")},
         // The ESLint rule will report fewer cases than our rule
+        "no-invalid-regexp": "off",
         "no-useless-backreference": "off",
 
         // eslint-plugin-regexp rules


Test patch:
diff --git a/tests/lib/eslint-plugin.ts b/tests/lib/eslint-plugin.ts
index 66ca24a..84cfb0a 100644
--- a/tests/lib/eslint-plugin.ts
+++ b/tests/lib/eslint-plugin.ts
@@ -1,6 +1,6 @@
 import path from "path"
 import assert from "assert"
-import { CLIEngine } from "eslint"
+import { ESLint } from "eslint"
 import plugin from "../../lib/index"
 
 // -----------------------------------------------------------------------------
@@ -10,16 +10,26 @@ import plugin from "../../lib/index"
 const TEST_CWD = path.join(__dirname, "../fixtures/integrations/eslint-plugin")
 
 describe("Integration with eslint-plugin-regexp", () => {
-    it("should lint without errors", () => {
-        const engine = new CLIEngine({
-            cwd: TEST_CWD,
-        })
-        engine.addPlugin("eslint-plugin-regexp", plugin)
-        const r = engine.executeOnFiles(["test.js"])
+    it("should lint without errors", async () => {
+        let results: ESLint.LintResult[]
+        if (ESLint) {
+            const eslint = new ESLint({
+                cwd: TEST_CWD,
+                plugins: { "eslint-plugin-regexp": plugin },
+            })
+            results = await eslint.lintFiles(["test.js"])
+        } else {
+            // eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports -- ignore
+            const engine = new (require("eslint").CLIEngine)({
+                cwd: TEST_CWD,
+            })
+            engine.addPlugin("eslint-plugin-regexp", plugin)
+            results = engine.executeOnFiles(["test.js"]).results
+        }
 
-        assert.strictEqual(r.results.length, 1)
+        assert.strictEqual(results.length, 1)
         assert.deepStrictEqual(
-            r.results[0].messages.map((m) => m.ruleId),
+            results[0].messages.map((m) => m.ruleId),
             [
                 "regexp/no-dupe-characters-character-class",
                 "regexp/prefer-w",
diff --git a/tests/lib/rules/letter-case.ts b/tests/lib/rules/letter-case.ts
index d79d36a..1d658f0 100644
--- a/tests/lib/rules/letter-case.ts
+++ b/tests/lib/rules/letter-case.ts
@@ -217,12 +217,11 @@ tester.run("letter-case", rule as any, {
             options: [{ unicodeEscape: "uppercase" }],
             errors: [String.raw`'\u{a}' is not in uppercase`],
         },
-        // TODO In the major version
-        // {
-        //     code: String.raw`/\x0A/`,
-        //     output: String.raw`/\x0a/`,
-        //     errors: [String.raw`'\x0A' is not in lowercase`],
-        // },
+        {
+            code: String.raw`/\x0A/`,
+            output: String.raw`/\x0a/`,
+            errors: [String.raw`'\x0A' is not in lowercase`],
+        },
         {
             code: String.raw`/\x0A/`,
             output: String.raw`/\x0a/`,
@@ -235,12 +234,11 @@ tester.run("letter-case", rule as any, {
             options: [{ hexadecimalEscape: "uppercase" }],
             errors: [String.raw`'\x0a' is not in uppercase`],
         },
-        // TODO In the major version
-        // {
-        //     code: String.raw`/\ca/u`,
-        //     output: String.raw`/\cA/u`,
-        //     errors: [String.raw`'\ca' is not in uppercase`],
-        // },
+        {
+            code: String.raw`/\ca/u`,
+            output: String.raw`/\cA/u`,
+            errors: [String.raw`'\ca' is not in uppercase`],
+        },
         {
             code: String.raw`/\cA/u`,
             output: String.raw`/\ca/u`,
diff --git a/tests/lib/rules/no-useless-lazy.ts b/tests/lib/rules/no-useless-lazy.ts
index 9d6029a..58e35c6 100644
--- a/tests/lib/rules/no-useless-lazy.ts
+++ b/tests/lib/rules/no-useless-lazy.ts
@@ -72,6 +72,11 @@ tester.run("no-useless-lazy", rule as any, {
             output: `/a+b+/`,
             errors: [{ messageId: "possessive" }],
         },
+        {
+            code: `/a*?b+/`,
+            output: `/a*b+/`,
+            errors: [{ messageId: "possessive" }],
+        },
         {
             code: `/(?:a|cd)+?(?:b+|zzz)/`,
             output: `/(?:a|cd)+(?:b+|zzz)/`,
diff --git a/tests/lib/rules/sort-alternatives.ts b/tests/lib/rules/sort-alternatives.ts
index 19e27c9..9650bcb 100644
--- a/tests/lib/rules/sort-alternatives.ts
+++ b/tests/lib/rules/sort-alternatives.ts
@@ -9,7 +9,7 @@ const tester = new RuleTester({
 })
 
 tester.run("sort-alternatives", rule as any, {
-    valid: [String.raw`/\b(?:a|\d+|c|b)\b/`],
+    valid: [String.raw`/\b(?:a|\d+|c|b)\b/`, String.raw`/\b(?:\^|c|b)\b/`],
     invalid: [
         {
             code: String.raw`/c|b|a/`,
@@ -103,5 +103,15 @@ tester.run("sort-alternatives", rule as any, {
                 "The alternatives of this group can be sorted without affecting the regex.",
             ],
         },
+
+        // sorting slices
+
+        {
+            code: String.raw`/\b(?:\^|c|b|a)\b/`,
+            output: String.raw`/\b(?:\^|a|b|c)\b/`,
+            errors: [
+                "The alternatives of this group can be sorted without affecting the regex.",
+            ],
+        },
     ],
 })