Skip to content
Switch branches/tags
Go to file


Failed to load latest commit information.
Latest commit message
Commit time


Actions Status npm

An ESLint plugin for writing better regular expressions.

⚠️ Deprecation announcement ⚠️

This project will be deprecated soon.

New users are advised to choose eslint-plugin-regexp instead.

Existing users can continue to use eslint-plugin-clean-regex.

What happened?

eslint-plugin-clean-regex and eslint-plugin-regexp have joined forces. We decided to work together on one ESLint plugin for JavaScript regexes. Since maintaining two plugins with similar rules takes too much work, I decided to stop working on eslint-plugin-clean-regex.

The now

We are currently adding all features of eslint-plugin-clean-regex to eslint-plugin-regexp. You can see our current progress here.

If you find bugs for eslint-plugin-clean-regex, you will still be able to file bug reports. However, bugs will only be fixed in eslint-plugin-regexp.

The future

eslint-plugin-clean-regex is going to be deprecated once all features have been added to eslint-plugin-regexp.

Existing users can expect a migration guide and a migration tool in the future to make the transition to eslint-plugin-regexp as easy as possible.

This announcement will be updated if anything happens.


This is an ESLint plugin to lint JavaScript regular expressions. Its goal is to help both beginners and experts to write better regular expressions by pointing out errors and suggesting improvements.

The plugin offers rules for possible errors, best practices, and coding style in regular expressions.

Right now, this project is still young (and many rules are opinionated). Feel free to open an issue if you think rules are too strict/lax/inflexible. Suggestions and feature requests are welcome as well!

Getting started

You'll need to install ESLint and eslint-plugin-clean-regex:

$ npm i eslint eslint-plugin-clean-regex --save-dev

Note: If you installed ESLint globally (using the -g flag) then you must also install eslint-plugin-clean-regex globally.

Add clean-regex to the plugins section of your .eslintrc configuration file (you can omit the eslint-plugin- prefix) and configure the rules you want:

    "plugins": [
    "rules": {
        "clean-regex/rule-name": 2

You can also use the recommended config:

    "plugins": [
    "extends": [

The setting of every rule in the recommended config can be found in the table below.


Some highlights of the working and working-together of rules in the recommended config.

Optimize character classes


- /[0-9]/i
- /[^\s]/
- /[a-fA-F0-9]/i
- /[a-zA-Z0-9_-]/
- /[a-z\d\w]/
- /[\S\d]/
- /[\w\p{ASCII}]/u


- /\d/
- /\S/
- /[a-f0-9]/i
- /[\w-]/
- /\w/
- /\S/
- /\p{ASCII}/u

Simplify patterns


- /(?:\w|\d)+/
- /(?:a|(b)|c|(?:d)|(?:ee)){0,}/
- /(?<!\w)a+(?=$)/mi
- /[\s\S]#[\0-\uFFFF]/ysi
- /\d*\w(?:[a-z_]|\d+)*/im


- /\w+/
- /(?:[acd]|(b)|ee)*/
- /\ba+$/im
- /.#./sy
- /\w+/

Detect non-functional code and potential errors

- /\1(a)/        // `\1` won't work
- /a+b*?/        // `b*?` can be removed
- /(?:\b)?a/     // `(?:\b)?` can be removed
- /[a-z]+|Foo/i  // `Foo` can be removed
- /(?=a?)\w\Ba/  // `(?=a?)` and `\B` always accept and can be removed
- /[*/+-^&|]/    // `+-^` will match everything from \x2B to \x5E including all character A to Z

Supported Rules

Fixable rules are denoted with a 🔧.


Rule Description
confusing-quantifier Warn about confusing quantifiers.
disjoint-alternatives Disallow different alternatives that can match the same words.
no-empty-alternative Disallow alternatives without elements.
no-empty-backreference Disallow backreferences that will always be replaced with the empty string.
no-empty-lookaround Disallow lookarounds that can match the empty string.
no-lazy-ends Disallow lazy quantifiers at the end of an expression.
no-obscure-range Disallow obscure ranges in character classes.
no-octal-escape Disallow octal escapes outside of character classes.
no-optional-assertion Disallow optional assertions.
no-potentially-empty-backreference Disallow backreferences that reference a group that might not be matched.
no-unnecessary-assertions Disallow assertions that are known to always accept (or reject).
🔧 no-zero-quantifier Disallow quantifiers with a maximum of 0.
optimal-lookaround-quantifier Disallows the alternatives of lookarounds that end with a non-constant quantifier.


Rule Description
🔧 consistent-match-all-characters Use one character class consistently whenever all characters have to be matched.
🔧 identity-escape How to handle identity escapes.
no-constant-capturing-group Disallow capturing groups that can match only one word.
🔧 no-trivially-nested-lookaround Disallow lookarounds that only contain another assertion.
🔧 no-trivially-nested-quantifier Disallow nested quantifiers that can be rewritten as one quantifier.
🔧 no-unnecessary-character-class Disallow unnecessary character classes.
🔧 no-unnecessary-flag Disallow unnecessary regex flags.
🔧 no-unnecessary-group Disallow unnecessary non-capturing groups.
🔧 no-unnecessary-lazy Disallow unnecessarily lazy quantifiers.
🔧 no-unnecessary-quantifier Disallow unnecessary quantifiers.
🔧 optimal-concatenation-quantifier Use optimal quantifiers for concatenated quantified characters.
🔧 optimized-character-class Disallows unnecessary elements in character classes.
🔧 prefer-character-class Prefer character classes wherever possible instead of alternations.
🔧 prefer-predefined-assertion Prefer predefined assertions over equivalent lookarounds.
🔧 prefer-predefined-character-set Prefer predefined character sets instead of their more verbose form.
🔧 prefer-predefined-quantifiers Prefer predefined quantifiers (+*?) instead of their more verbose form.
🔧 simple-constant-quantifier Prefer simple constant quantifiers over the range form.
🔧 sort-flags Requires the regex flags to be sorted.