xregexp

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

Library
npm
v5.1.2
3,327stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
60/100Good
Development Activity52
Maintenance24
Community64
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
79/100Good
Architecture80
Code Quality82
Innovation70
Learning Curve85

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

Search