eslint-plugin-regex

Looks for Invalid regular expressions to be reported for each file

Rule Details

This rule looks for Invalid regular expressions to be reported for each file.

Example of incorrect code for this rule:

/* eslint regex/invalid: ['error', ['"']] */

const text = 'Hello "My Friend"'

Example of correct code for this rule:

/* eslint regex/invalid: ['error', ['"']] */

const text = 'Hello \'My Friend\''

Options

Short pattern definition

It is specified by just a regular expression string, i.e. "regex"

.eslintrc.json:

{
  "plugins": [
    "regex"
  ],
  "rules": {
    "regex/invalid": [
      "error", [
        "invalidRegex1",
        "invalidRegexN"
      ],
      ".*test\\.js"
    ]
  }
}

Detailed pattern definition

It is specified by an object, with the following fields:

{
  "id": "regexId",
  "regex": "regex",
  "flags": "isu",
  "replacement": "replacementString",
  "message": "errorMessage",
  "files": {
    "ignore": "ignoreFilesRegex",
    "inspect": "inspectFilesRegex"
  }
}

[1] In order to fix issue eslint must be run with --fix option.

.eslintrc.json:

{
  "plugins": [
    "regex"
  ],
  "rules": {
    "regex/invalid": [
      "error", [{
          "regex": "invalidRegex1",
          "message": "errorMessage1",
          "replacement": "newValue"
        }, {
          "id": "regexIdN",
          "regex": "invalidRegexN",
          "files": {
            "ignore": "ignoreFilesRegexN"
          }
        }
      ]
    ]
  }
}

Definition of the Function used to replace the invalid found pattern

Definition of the function must be done as a string in 1 line, and the following rules apply:

Function will receive 3 parameters, to be used as desired:

e.g. Using parameter text

"return text.trim()" => only the body of the function + returns a string value based on text

Having the following rule in .eslintrc.json:

{
  "id": "regexIdN",
  "regex": "\\serror\\w*\\s",
  "replacement": {
    "function": "return text.trim()"
  }
}

or using $:

{
  "id": "regexIdN",
  "regex": "\\serror\\w*\\s",
  "replacement": {
    "function": "return $[0].trim()"
  }
}

then, given:

example.js

const exception = " error19 "

when linting with fix, the result will be:

const exception = "error19"

As the body of the function is “simple”, i.e. the return is found at the beginning of the body of the function, and besides, the word return is not present, then the definition could be done as:

{
  "id": "regexIdN",
  "regex": "\\serror\\w*\\s",
  "replacement": {
    "function": "text.trim()"
  }
}

or

{
  "id": "regexIdN",
  "regex": "\\serror\\w*\\s",
  "replacement": {
    "function": "$[0].trim()"
  }
}

e.g. Using parameter captured

"return captured[0]" => only the body of the function + returns a string value based on captured

Having the following rule in .eslintrc.json:

{
  "id": "regexIdN",
  "regex": "\\serror(\\w*)\\s",
  "replacement": {
    "function": "return captured[0]"
  }
}

or using $:

{
  "id": "regexIdN",
  "regex": "\\serror(\\w*)\\s",
  "replacement": {
    "function": "return $[1]"
  }
}

then, given:

example.js

const exception = " error19 "

when linting with fix, the result will be:

const exception = "19"

As the body of the function is “simple”, i.e. the return is found at the beginning of the body of the function, and besides, the word return is not present, then the definition could be done as:

{
  "id": "regexIdN",
  "regex": "\\serror(\\w*)\\s",
  "replacement": {
    "function": "captured[0]"
  }
}

or

{
  "id": "regexIdN",
  "regex": "\\serror(\\w*)\\s",
  "replacement": {
    "function": "$[1]"
  }
}

e.g. Using parameters text and captured

"return text + ' = ' + captured[0] + ' + ' + captured[1] + ' = ' + (parseInt(captured[0]) + parseInt(captured[1]))" => only the body of the function + returns a string value based on text and captured

Having the following rule in .eslintrc.json:

{
  "id": "regexIdN",
  "regex": "(\\d+)\\+(\\d+)",
  "replacement": {
    "function": "return text + ' = ' + captured[0]  + ' + ' + captured[1] + ' = ' + (parseInt(captured[0]) + parseInt(captured[1]))"
  }
}

or using $:

{
  "id": "regexIdN",
  "regex": "(\\d+)\\+(\\d+)",
  "replacement": {
    "function": "return $[0] + ' = ' + $[1]  + ' + ' + $[2] + ' = ' + (parseInt($[1]) + parseInt($[2]))"
  }
}

or :

{
  "id": "regexIdN",
  "regex": "(\\d+)\\+(\\d+)",
  "replacement": {
    "function": "return text + ' = ' + $[1]  + ' + ' + $[2] + ' = ' + (parseInt($[1]) + parseInt($[2]))"
  }
}

or :

{
  "id": "regexIdN",
  "regex": "(\\d+)\\+(\\d+)",
  "replacement": {
    "function": "return `${text} = ${captured[0]} + ${captured[1]} = ${parseInt($[1]) + parseInt($[2])}`"
  }
}

then, given:

example.js

const sum = "4+5"

when linting with fix, the result will be:

const sum = "4+5 = 4 + 5 = 9"

As the body of the function is “simple”, i.e. the return is found at the beginning of the body of the function, and besides, the word return is not present, then the definition could be done as:

{
  "id": "regexIdN",
  "regex": "(\\d+)\\+(\\d+)",
  "replacement": {
    "function": "text + ' = ' + $[1]  + ' + ' + $[2] + ' = ' + (parseInt($[1]) + parseInt($[2]))"
  }
}

or :

{
  "id": "regexIdN",
  "regex": "(\\d+)\\+(\\d+)",
  "replacement": {
    "function": "`${text} = ${captured[0]} + ${captured[1]} = ${parseInt($[1]) + parseInt($[2])}`"
  }
}

e.g. return required

e.g. const result = text === 'superb' ? 'Superb' : text; return result => only the body of the function + returns a string value based on text.

Since the return is not found at the beginning of the body of the function, return cannot be omitted, then rule definition will be as usual:

{
  "id": "regexIdN",
  "regex": "\\w+",
  "replacement": {
    "function": "const result = text === 'superb' ? 'Superb' : text; return result"
  }
}

Some cases may use Comma operator, e.g. "function": "result = text === 'superb' ? 'Superb' : text, result"

e.g. return text === 'return' ? 'Return' : text => only the body of the function + returns a string value based on text.

Since the exact word return is present, this will required return, then rule definition will be as usual:

{
  "id": "regexIdN",
  "regex": "\\w+",
  "replacement": {
    "function": "return text === 'return' ? 'Return' : text"
  }
}

Following case does not required return:

e.g. return text === 'Return' ? 'RETURN' : text => only the body of the function + returns a string value based on text.

Since the exact word return is not present, this will allow the following rule definition to be:

{
  "id": "regexIdN",
  "regex": "\\w+",
  "replacement": {
    "function": "text === 'Return' ? 'RETURN' : text"
  }
}
Debugging of the Replacement Function for invalid found pattern
{
      regex: '\\serror(\\w*)\\s',
      replacement: {
        function: 'const extract = captured[0]; console.log(extract); return extract'
      }
    }

String to Regular expression conversion

Internally, each string from the array will be converted into a Regular Expression with global and multiline options, e.g.:

"invalidRegex1" will be transformed into /invalidRegex1/gm

When the pattern is found, the error message will reflect the exact location, e.g.:

 34:25  error  Invalid regular expression /invalidRegex1/gm found  regex/invalid

Examples

Check:

More information