Drizzle-inspired, fluent-API Regex builder for modern TypeScript. Automatically infers named capture groups, ensures stateless execution, and compiles to native RegExp.
We believe regular expressions shouldn't feel like deciphering an ancient language. We bring the safety of modern ORMs to your regex engine.
Named captures instantly become strongly-typed objects. No more as string.
const reg = rx()
.capture('id', rx().digit())
.compile();
// result.id is strictly inferred as string!
const result = reg.exec('5');
We auto-escape special characters. You literally cannot inject a malformed string.
// Safely compiles to [a\-z], NOT a range!
rx().anyOf('a-z');
// Correct, type-safe composition:
rx().range('a', 'z');
Global regex iteration in JS is notoriously buggy. We instantiate fresh wrappers natively.
// Global match returns an IterableIterator
const matches = pattern.global().compile();
// LastIndex will never leak! Completely stateless.
for (const match of matches.exec('...')) {}
No heavy runtime bloat. TS-Rex compiles down to pure, native JavaScript RegExp.
// No heavy JS engines, just pure standard RegExp.
const nativeRegex = rx().literal('fast').compile().native;
nativeRegex.test('fast'); // true
Regex union types and optional groups are incredibly hard to type correctly. We built a meta-programming engine that traverses your AST at compile time to apply Partial<T> and Union types automatically.
Wrap any capture in .optional() or .or(), and TypeScript instantly knows those variables might be undefined.
import { rx } from '@fajarnugraha37/ts-rex';
const b = rx()
.capture('a', rx().literal('A'))
.or(rx().capture('b', rx().literal('B')))
.compile();
const result = b.exec('A');
if (result.isMatch) {
// TS enforces mutual exclusivity
// If 'a' exists, 'b' is undefined, and vice versa.
console.log(result.a);
}
Monolithic regex strings are impossible to read or review in Pull Requests. TS-Rex lets you compose massive parsers out of tiny, unit-testable blocks. Combine and reuse patterns endlessly.
const domainChars = rx()
.range('a', 'z')
.or(rx().range('0', '9'))
.or(rx().anyOf('.-'));
const urlParser = rx()
.startOfInput()
.literal('https://')
// Pass the composed class cleanly
.capture('domain', rx().oneOrMore(domainChars))
.endOfInput()
.compile();
We fully support the newest ECMAScript regex features natively. Use the v flag for Unicode Sets and the d flag for Match Indices. TS-Rex will automatically type and extract the runtime index tuples for you!
// Inject ES2024 'v' flag and 'd' indices flag
const b = rx()
.capture('val', rx().unicodeProperty('Emoji'))
.unicodeSets()
.withIndices()
.compile();
const result = b.exec('🔥');
// Automatically maps match.indices back to the result!
console.log(result.indices.val); // [0, 2]
Tested on the edge. Built to integrate anywhere.