Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/fajarnugraha37/ts-rex/llms.txt

Use this file to discover all available pages before exploring further.

Flags modify how the regex engine interprets and executes a pattern. In TS-Rex, flag methods are more than thin wrappers around the native RegExp flag letters — several of them alter the TypeScript return type of .exec() in a way that is tracked through the TFlags generic parameter. Calling .global() changes the return type from a single-match discriminated union to an IterableIterator. Calling .withIndices() adds an indices property to every successful match. The table below summarises the type-level impact of each flag, followed by full method references.

Flag summary

MethodFlag letterTFlags key setReturn type effect
.global()g{ global: true }exec() returns IterableIterator<SingleMatch>
.ignoreCase()i{ ignoreCase: true }No change to return type
.multiline()m{ multiline: true }No change to return type
.dotAll()s{ dotAll: true }No change to return type
.withIndices()d{ hasIndices: true }Adds indices property to SingleMatch
.unicode()u{ unicode: true }No change to return type
.unicodeSets()v{ unicodeSets: true }No change to return type
.sticky()y{ sticky: true }No change to return type

.global()

Enables global matching. The g flag causes .exec() to find all non-overlapping matches across the entire input instead of stopping at the first. At the type level, TFlags is widened to include { global: true }, which changes MatchResult from SingleMatch | FailedMatch to IterableIterator<SingleMatch>. Signature
global(): RegexBuilder<TCaptures, Omit<TFlags, 'global'> & { global: true }>
Return type when global: true
type MatchResult<TCaptures, { global: true }> =
  IterableIterator<SingleMatch<TCaptures, TFlags>>;
Because the return is always an iterator (never FailedMatch), you do not use an if (result.isMatch) guard — you iterate directly. An empty iterator means no matches were found. Example
import { rx } from '@fajarnugraha37/ts-rex';

const pattern = rx()
  .capture('num', rx().oneOrMore(rx().digit()))
  .global()
  .compile();

const results = pattern.exec('I have 3 apples and 42 bananas');

for (const result of results) {
  console.log(result.num); // "3", then "42"
}
TS-Rex creates a fresh RegExp instance on every .exec() call. This eliminates the lastIndex bug that affects native global regexes, where a second call on the same RegExp instance resumes from a stale position.

.ignoreCase()

Enables case-insensitive matching. The i flag causes the engine to treat uppercase and lowercase letters as equivalent. Signature
ignoreCase(): RegexBuilder<TCaptures, Omit<TFlags, 'ignoreCase'> & { ignoreCase: true }>
Example
import { rx } from '@fajarnugraha37/ts-rex';

const pattern = rx()
  .capture('greeting', rx().literal('hello'))
  .ignoreCase()
  .compile();

const result = pattern.exec('Hello, world!');

if (result.isMatch) {
  console.log(result.greeting); // "Hello"
}

.multiline()

Enables multiline mode. The m flag changes the meaning of ^ and $ so they match the start and end of each line within the string, not just the start and end of the entire input. Signature
multiline(): RegexBuilder<TCaptures, Omit<TFlags, 'multiline'> & { multiline: true }>
Example
import { rx } from '@fajarnugraha37/ts-rex';

const pattern = rx()
  .startOfInput()
  .capture('line', rx().oneOrMore(rx().notWhitespace()))
  .multiline()
  .global()
  .compile();

const results = pattern.exec('first\nsecond\nthird');

for (const result of results) {
  console.log(result.line); // "first", "second", "third"
}

.dotAll()

Enables dotAll mode. The s flag causes .anyChar() (.) to match any character including newline characters (\n, \r, \u2028, \u2029). Without this flag, . does not match newlines. Signature
dotAll(): RegexBuilder<TCaptures, Omit<TFlags, 'dotAll'> & { dotAll: true }>
Example
import { rx } from '@fajarnugraha37/ts-rex';

const pattern = rx()
  .literal('<')
  .capture('content', rx().oneOrMore(rx().anyChar()))
  .literal('>')
  .dotAll()
  .compile();

const result = pattern.exec('<line one\nline two>');

if (result.isMatch) {
  console.log(result.content); // "line one\nline two"
}

.withIndices()

Enables indices mode. The d flag causes the engine to compute start and end character indices for the full match and every named capture group. At the type level, TFlags is widened to include { hasIndices: true }, which adds a readonly indices property to SingleMatch. Signature
withIndices(): RegexBuilder<TCaptures, Omit<TFlags, 'hasIndices'> & { hasIndices: true }>
Type impact on SingleMatch
type SingleMatch<TCaptures, { hasIndices: true }> =
  TCaptures &
  { isMatch: true; match: string } &
  { readonly indices: Record<keyof TCaptures, [number, number]> & { match: [number, number] } };
Each entry in indices is a [start, end] tuple where start is the inclusive start index and end is the exclusive end index, matching the slice convention of String.prototype.slice. Example
import { rx } from '@fajarnugraha37/ts-rex';

const pattern = rx()
  .capture('word', rx().oneOrMore(rx().wordChar()))
  .withIndices()
  .compile();

const result = pattern.exec('hello world');

if (result.isMatch) {
  console.log(result.word);           // "hello"
  console.log(result.indices.match);  // [0, 5]
  console.log(result.indices.word);   // [0, 5]
}
The indices property key is hasIndices internally (matching the RegExp.prototype.hasIndices property name), even though the flag letter is d. Use .withIndices() — not .hasIndices() — to enable this mode.

.unicode()

Enables Unicode mode. The u flag treats the pattern and the input as a sequence of Unicode code points rather than UTF-16 code units. This is required for .unicodeCodePoint() (\u{...}) and .unicodeProperty() (\p{...}) to work correctly. Signature
unicode(): RegexBuilder<TCaptures, Omit<TFlags, 'unicode'> & { unicode: true }>
Example
import { rx } from '@fajarnugraha37/ts-rex';

const pattern = rx()
  .capture('emoji', rx().unicodeProperty('Emoji'))
  .unicode()
  .compile();

const result = pattern.exec('Hello 🎉');

if (result.isMatch) {
  console.log(result.emoji); // "🎉"
}

.unicodeSets()

Enables Unicode sets mode (ES2024). The v flag is a superset of u, additionally enabling set operations (--, &&) and string literals inside character classes. You cannot use both u and v flags on the same regex. Signature
unicodeSets(): RegexBuilder<TCaptures, Omit<TFlags, 'unicodeSets'> & { unicodeSets: true }>
The v flag (Unicode sets) is an ES2024 feature. It is not available in Node.js versions below 20 or in older browsers. Check your target environment before using .unicodeSets().
Example
import { rx } from '@fajarnugraha37/ts-rex';

const pattern = rx()
  .unicodeProperty('Decimal_Number')
  .unicodeSets()
  .compile();

const result = pattern.exec('price: 42');

if (result.isMatch) {
  console.log(result.match); // "4"
}

.sticky()

Enables sticky mode. The y flag causes the engine to match only at the exact position indicated by lastIndex on the underlying RegExp instance. Because TS-Rex creates a fresh RegExp on every .exec() call (with lastIndex starting at 0), sticky mode effectively anchors the match to the start of the string unless you interact with compiled.native directly. Signature
sticky(): RegexBuilder<TCaptures, Omit<TFlags, 'sticky'> & { sticky: true }>
Example
import { rx } from '@fajarnugraha37/ts-rex';

const pattern = rx()
  .capture('token', rx().oneOrMore(rx().wordChar()))
  .sticky()
  .compile();

// Matches at position 0 — success
const result = pattern.exec('hello world');

if (result.isMatch) {
  console.log(result.token); // "hello"
}

// Does not match mid-string because exec() always starts at lastIndex = 0
const result2 = pattern.exec('   hello');
console.log(result2.isMatch); // false
If you need to advance through a string position by position using sticky mode, access compiled.native to work with the underlying RegExp instance directly and manage lastIndex yourself.

Build docs developers (and LLMs) love