xregexp

Extended, extensible JavaScript regular expressions with named capture, Unicode properties, free-spacing syntax, and a regex utility belt.

Library
npm
v5.1.3
3,325 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
69 /100 Good
Development Activity 68
Maintenance 44
Community 64
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
79 /100 Good
Architecture 80
Code Quality 82
Innovation 70
Learning Curve 85

XRegExp augments native JavaScript regular expressions with syntax and flags that browsers didn’t originally support natively, including named capture groups, Unicode categories/scripts/properties, free-spacing mode (flag x), and sticky matching. Because XRegExp compiles down to native RegExp objects, regexes built with it run at native speed, with only a small one-time compilation cost the first time a pattern is used.

Beyond syntax extensions, the library ships a set of higher-level utilities: XRegExp.build and the XRegExp.tag template-literal helper for composing readable regexes out of named subpatterns, XRegExp.matchRecursive for parsing nested/balanced constructs like tags or parentheses that plain regex alone can’t express, and XRegExp.matchChain/XRegExp.forEach for chained and iterative matching. Many of XRegExp’s original innovations (named capture, Unicode property escapes, the s and d flags, sticky matching) have since been standardized into JavaScript itself, and the project’s README now points newer projects at its lighter-weight spiritual successor, Regex+ — but XRegExp remains a stable, widely-used way to get that behavior in older runtimes or in codebases already built on it.

What You Get

  • Named capture groups exposed on match.groups, following the ES2018 convention
  • Unicode-aware \p{...}/\P{...} property, category, and script matching, including full 21-bit astral-mode support via flag A
  • Free-spacing/comment mode (flag x) for writing self-documenting, multi-line regex patterns
  • XRegExp.build and XRegExp.tag for composing large regexes out of small, named, reusable subpatterns with automatic backreference renumbering
  • XRegExp.matchRecursive for matching balanced/nested delimiters (tags, brackets, braces) that native regex cannot express
  • XRegExp.matchChain and XRegExp.forEach for running a string through a pipeline of regexes or iterating matches with an index callback
  • XRegExp.union for merging multiple strings/regexes into one pattern with correctly renumbered backreferences

Common Use Cases

  • Parsing dates, log lines, or structured text with self-documenting named-capture patterns instead of positional groups
  • Validating or extracting Unicode text (non-Latin scripts, emoji, accented characters) in form input or text-processing pipelines
  • Extracting values from nested/recursive structures such as HTML tags, balanced parentheses, or templating delimiters
  • Building large, composable regexes from smaller named fragments to keep complex patterns maintainable
  • Backporting modern regex features (named groups, Unicode property escapes, sticky flag) into codebases that must support older JavaScript engines

Under The Hood

Architecture The core (src/xregexp.js) is a single-file engine built around a private token-registration system: XRegExp.addToken registers custom syntax handlers keyed to a default or character-class scope, and the XRegExp() constructor tokenizes an extended pattern string through these handlers before handing a plain string to the native RegExp constructor — meaning every XRegExp object literally is a RegExp instance with extra metadata stashed under a private xregexp property (capture names, whether it’s sticky-only, etc.). Six addons (build, matchrecursive, unicode-base, unicode-categories, unicode-properties, unicode-scripts) are separate modules that each take the core XRegExp object as a parameter and register additional tokens or static methods onto it — src/index.js is just the composition root that imports the core and calls each addon function in sequence, so the whole system is an explicit plugin/registration pattern rather than an inheritance hierarchy. Because the constructor compiles down to native RegExp, there’s no runtime interpretation layer degrading match performance; all the extension work happens once, at construction time.

Tech Stack The published package targets plain JavaScript with no runtime dependencies of its own beyond a Babel corejs polyfill (@babel/runtime-corejs3) pulled in for older-engine compatibility. Source is authored in modern ES modules under src/ and compiled to CommonJS (lib/) via Babel (@babel/preset-env, plus a project-specific babel-plugin-transform-xregexp and babel-plugin-add-module-exports), with a browser bundle produced by Browserify (xregexp-all.js, exposed as a XRegExp global). Unicode category/property/script tables are generated ahead of time from the @unicode/unicode-14.0.0 and unicode-property-value-aliases datasets via scripts in tools/, rather than computed at runtime. TypeScript consumers get a hand-maintained types/index.d.ts declaration file.

Code Quality Tests are extensive and use Jasmine (tests/spec/, several thousand lines across five spec files covering the core engine, method-level behavior, and each addon) run under nyc for coverage, with a custom Jasmine matcher (addToEqualMatchMatcher) for asserting on match arrays including named groups. ESLint is configured project-wide (.eslintrc.js, plus a stricter tests/.eslintrc.js) and wired into the prebuild script, so lint failures block a release build. Error handling favors explicit thrown Error/SyntaxError with descriptive messages over silent failures (e.g. unbalanced-delimiter detection in matchRecursive has multiple explicit user-selectable handling modes). Naming is consistent and the public API surface is well documented inline with JSDoc-style comments throughout the core and addons.

What Makes It Unique XRegExp’s defining technical choice is that its extensions compile to native RegExp objects rather than maintaining a parallel regex engine, so there’s effectively zero runtime matching overhead versus hand-written native regex — the cost is paid once, at pattern-construction time, via the token-registration compiler. matchRecursive is the standout capability: genuine balanced/nested-construct matching (something regular expressions are formally incapable of expressing on their own) implemented as a hybrid regex-plus-stack-based scanner. Its historical significance is notable too — many of its original extensions (named capture, Unicode property escapes, the s/d/sticky flags) were later adopted into the ECMAScript standard itself, which the project’s own README now acknowledges by pointing newer users toward its lighter successor, Regex+, for cases where native support already covers what’s needed.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers