regex logo

[![npm version][npm-version-src]][npm-version-href] [![npm downloads][npm-downloads-src]][npm-downloads-href] [![bundle][bundle-src]][bundle-href]

The Regex+ library (package name: regex) provides a template tag named regex. This tag modernizes JavaScript regular expressions with always-on best practices and support for new features that make regexes more powerful and dramatically more readable. The regex tag returns native RegExp instances that run with native performance and can exceed the performance of regex literals you’d write yourself.

With the Regex+ library, JavaScript steps up as one of the best regex flavors alongside PCRE and Perl, possibly surpassing C++, Java, .NET, Python, and Ruby.

Features added to native JavaScript regular expressions include insignificant whitespace and comments for readability, atomic groups and possessive quantifiers that can help you avoid ReDoS, subroutines and subroutine definition groups that enable grammatical patterns with powerful subpattern composition, and context-aware interpolation of regexes, escaped strings, and partial patterns.

Details:

  • Lightweight (7 kB minzip)
  • Available as a Babel plugin, which avoids any runtime dependencies or user runtime cost
  • Supports all ES2025 regex features
  • Type definitions included

πŸ“œ Contents

πŸ’Ž Features

A modern regex baseline so you don’t need to continually opt-in to best practices.

  • Always-on flag v gives you the best level of Unicode support and strict errors.
  • New flags:
    • Always-on flag x allows you to freely add whitespace and comments to your regexes.
    • Always-on flag n (β€œnamed capture only” mode) improves regex readability and efficiency.
  • No unreadable escaped backslashes \\\\ since it’s a raw string template tag.

Extended regex syntax.

  • Atomic groups and possessive quantifiers can dramatically improve performance and prevent ReDoS.
  • Subroutines and definition groups enable powerful composition, improving readability and maintainability.
  • Recursive matching via an official plugin.
  • Custom syntax plugins supported.

Context-aware and safe interpolation of regexes, strings, and partial patterns.

  • Interpolated strings have their special characters escaped.
  • Interpolated regexes locally preserve the meaning of their own flags (or their absense), and their numbered backreferences are adjusted to work within the overall pattern.

πŸ•ΉοΈ Install and use

Copied!
npm install regex
Copied!
import {regex} from 'regex';

// Works with all string/regexp methods since it returns a native regexp
const str = 'abc';
regex`\w`.test(str); // β†’ true
str.match(regex('g')`\w`); // β†’ ['a', 'b', 'c']
In browsers ESM: ```html ``` Using a global name: ```html ```

πŸͺ§ Examples

Copied!
import {regex, pattern} from 'regex';

// Subroutines and a subroutine definition group
// Also shows insignificant whitespace for readability
const record = regex`
  ^ Admitted: \g<date> \n
    Released: \g<date> $

  (?(DEFINE)
    (?<date>  \g<year>-\g<month>-\g<day>)
    (?<year>  \d{4})
    (?<month> \d{2})
    (?<day>   \d{2})
  )
`;

// Atomic group: Avoids ReDoS from the nested, overlapping quantifier
const words = regex`^(?>\w+\s?)+$`;

// Context-aware interpolation
// Also shows line comments and insignificant whitespace
const re = regex('m')`
  # RegExp: Only the inner regex is case insensitive (flag i), and the outer
  # regex's flags (including implicit flag x) don't apply to it
  ${/^a.$/i}
  |
  # String: Regex special chars are escaped
  # Note that quantifying an interpolated value repeats it as a complete unit
  ${'a|b'}+
  |
  # Pattern: This string is contextually sandboxed but not escaped
  [${pattern('a-z')}]
`;

// Numbered backreferences in interpolated regexes are adjusted
const double = /(.)\1/;
regex`^ (?<first>.) ${double} ${double} $`;
// β†’ /^(?<first>.)(.)\2(.)\3$/v
Show examples of using subroutine definition groups to refactor previously unmaintainable regexes ### Date/time regex ```js // Unmaintainable regex from real-world code for validating a date and time const DATE_FILTER_RE = /^(since|until):((?!0{3})\d{4}(?:-(?:0[1-9]|1[0-2])(?:-(?:0[1-9]|[12]\d|3[01])(?:T(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|(?!-00:00)[+-](?:[01]\d|2[0-3]):(?:[0-5]\d))?)?)?)?)$/; // Refactored for Regex+, with identical matches // Includes a subroutine definition group at the bottom const DATE_FILTER_RE = regex` ^ (?fix> since | until) : (? \g (- \g (- \g (T \g