CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-xregexp

Extended regular expressions with augmented syntax, named capture groups, Unicode support, and cross-browser compatibility

Overview
Eval results
Files

pattern-building.mddocs/

Pattern Building and Utilities

Advanced pattern construction tools including named subpatterns, template literals, and pattern combination utilities.

Capabilities

Build Method

Builds regexes using named subpatterns with automatic backreference renumbering.

/**
 * Builds regexes using named subpatterns for readability and pattern reuse
 * @param pattern - XRegExp pattern using {{name}} for embedded subpatterns
 * @param subs - Lookup object for named subpatterns (values can be strings or regexes)
 * @param flags - Any combination of XRegExp flags
 * @returns Regex with interpolated subpatterns
 */
function build(pattern: string, subs: Record<string, string | RegExp>, flags?: string): RegExp;

Usage Examples:

// Basic subpattern building
const time = XRegExp.build('(?x)^ {{hours}} ({{minutes}}) $', {
  hours: XRegExp.build('{{h12}} : | {{h24}}', {
    h12: /1[0-2]|0?[1-9]/,
    h24: /2[0-3]|[01][0-9]/
  }, 'x'),
  minutes: /^[0-5][0-9]$/
});

time.test('10:59'); // true
XRegExp.exec('10:59', time).groups.minutes; // '59'

// Shorthand for named groups: ({{name}}) becomes (?<name>{{name}})
const urlPattern = XRegExp.build('({{protocol}})://({{domain}})({{path}})?', {
  protocol: 'https?',
  domain: '[\\\\w.-]+',
  path: '/.*'
});

Tag Method

Creates tagged template literal handler for regex construction with XRegExp syntax.

/**
 * Creates tagged template literal handler for regex construction
 * @param flags - Any combination of XRegExp flags
 * @returns Handler for template literals that construct regexes with XRegExp syntax
 */
function tag(flags?: string): (literals: TemplateStringsArray, ...substitutions: any[]) => RegExp;

Usage Examples:

// Basic tagged template usage
XRegExp.tag()`\\\\b\\\\w+\\\\b`.test('word'); // true

// With flags and interpolation
const hours = /1[0-2]|0?[1-9]/;
const minutes = /(?<minutes>[0-5][0-9])/;
const time = XRegExp.tag('x')`\\\\b ${hours} : ${minutes} \\\\b`;

time.test('10:59'); // true
XRegExp.exec('10:59', time).groups.minutes; // '59'

// Backreference rewriting in interpolated regexes
const backref1 = /(a)\\\\1/;
const backref2 = /(b)\\\\1/;
XRegExp.tag()`${backref1}${backref2}`.test('aabb'); // true

Union Method

Creates union of multiple patterns with backreference renumbering.

/**
 * Returns XRegExp object that is union of given patterns
 * @param patterns - Array of regexes and strings to combine
 * @param flags - Any combination of XRegExp flags
 * @param options - Options object with conjunction property
 * @returns Union of the provided regexes and strings
 */
function union(patterns: (string | RegExp)[], flags?: string, options?: UnionOptions): RegExp;

interface UnionOptions {
  conjunction?: 'or' | 'none';
}

Usage Examples:

// Standard union with 'or' conjunction
XRegExp.union(['a+b*c', /(dogs)\\\\1/, /(cats)\\\\1/], 'i');
// Result: /a\\+b\\*c|(dogs)\\1|(cats)\\2/i

// Concatenation with 'none' conjunction
XRegExp.union([/man/, /bear/, /pig/], 'i', {conjunction: 'none'});
// Result: /manbearpig/i

// Mixed patterns with automatic escaping
XRegExp.union([
  'literal.string',  // Escaped: literal\\.string
  /\\d+/,            // Used as-is with backreference renumbering
  '(optional)?'      // Escaped: \\(optional\\)\\?
], 'g');

Escape Method

Escapes regex metacharacters for literal matching.

/**
 * Escapes any regular expression metacharacters for literal string matching
 * @param str - String to escape
 * @returns String with regex metacharacters escaped
 */
function escape(str: string): string;

Usage Examples:

// Basic escaping
XRegExp.escape('Escaped? <.>');
// Result: 'Escaped\\?\\u0020<\\.>'

// Safe for use in any regex context
const userInput = 'user.input[special]';
const literal = XRegExp.escape(userInput);
const regex = XRegExp(`start${literal}end`);

// Useful for building dynamic patterns
const searchTerms = ['hello.world', 'test[case]', 'special?chars'];
const escapedTerms = searchTerms.map(XRegExp.escape);
const pattern = XRegExp.union(escapedTerms, 'gi');

Subpattern Features

Named Subpattern Syntax

The build method supports several subpattern syntaxes:

// Basic substitution: {{name}}
const basic = XRegExp.build('{{digit}}+', {
  digit: '\\\\d'
});

// Named group shorthand: ({{name}}) becomes (?<name>{{name}})
const named = XRegExp.build('({{year}})-({{month}})', {
  year: '\\\\d{4}',
  month: '\\\\d{2}'
});
// Equivalent to: (?<year>\\d{4})-(?<month>\\d{2})

Automatic Deanchoring

Leading ^ and trailing $ are automatically stripped from subpatterns:

const pattern = XRegExp.build('start{{middle}}end', {
  middle: /^\\d+$/  // Anchors are stripped
});
// Result pattern can match within larger strings

Backreference Renumbering

Backreferences in subpatterns are automatically renumbered:

const pattern = XRegExp.build('{{first}}{{second}}', {
  first: /(\\w)\\1/,    // Uses \\1
  second: /(\\d)\\1/    // \\1 becomes \\2 in final pattern
});
// Final pattern handles backreferences correctly

Template Literal Features

Raw String Handling

Template literals handle backslashes as raw strings:

// No need to double-escape backslashes
const regex1 = XRegExp.tag()`\\d+\\w*`;      // Works correctly
const regex2 = XRegExp('\\\\d+\\\\w*');      // Equivalent but requires escaping

Interpolation with Type Safety

Interpolated values are processed safely:

// Strings are escaped, regexes preserve structure
const userPattern = 'user.input';  // String - will be escaped
const numberPattern = /\\d+/;      // Regex - used as-is

const combined = XRegExp.tag()`${userPattern}:${numberPattern}`;
// userPattern becomes literal, numberPattern remains regex

Backreference Preservation

Backreferences in interpolated regexes are rewritten for the combined pattern:

const pattern1 = /(.)\\1/;     // Matches doubled characters
const pattern2 = /(.)\\1/;     // Another doubled character pattern

const combined = XRegExp.tag()`${pattern1}-${pattern2}`;
// Backreferences are renumbered: /(.)\\1/-(.)\\2/
combined.test('aa-bb'); // true

Advanced Pattern Construction

Nested Building

Build patterns can be nested for complex constructions:

const timePattern = XRegExp.build('{{time}}', {
  time: XRegExp.build('{{hours}}:{{minutes}}', {
    hours: XRegExp.build('{{h12}}|{{h24}}', {
      h12: '1[0-2]|0?[1-9]',
      h24: '2[0-3]|[01][0-9]'
    }),
    minutes: '[0-5][0-9]'
  })
});

Mode Modifiers

Inline mode modifiers affect the entire built pattern:

const pattern = XRegExp.build('(?xi) {{spaced}} {{pattern}}', {
  spaced: 'word1   word2',  // Spaces ignored due to x flag
  pattern: '# This is a comment\\n\\\\d+'
});

Dynamic Pattern Generation

Combine with JavaScript for dynamic pattern creation:

function createChoicePattern(choices, flags = '') {
  const escapedChoices = choices.map(XRegExp.escape);
  return XRegExp.union(escapedChoices, flags);
}

// Create pattern matching any of the provided options
const keywords = ['class', 'function', 'const', 'let'];
const keywordPattern = createChoicePattern(keywords, 'gi');

Install with Tessl CLI

npx tessl i tessl/npm-xregexp

docs

advanced-matching.md

construction.md

execution.md

extensibility.md

index.md

pattern-building.md

string-processing.md

unicode-support.md

tile.json