0
# Pattern Building and Utilities
1
2
Advanced pattern construction tools including named subpatterns, template literals, and pattern combination utilities.
3
4
## Capabilities
5
6
### Build Method
7
8
Builds regexes using named subpatterns with automatic backreference renumbering.
9
10
```javascript { .api }
11
/**
12
* Builds regexes using named subpatterns for readability and pattern reuse
13
* @param pattern - XRegExp pattern using {{name}} for embedded subpatterns
14
* @param subs - Lookup object for named subpatterns (values can be strings or regexes)
15
* @param flags - Any combination of XRegExp flags
16
* @returns Regex with interpolated subpatterns
17
*/
18
function build(pattern: string, subs: Record<string, string | RegExp>, flags?: string): RegExp;
19
```
20
21
**Usage Examples:**
22
23
```javascript
24
// Basic subpattern building
25
const time = XRegExp.build('(?x)^ {{hours}} ({{minutes}}) $', {
26
hours: XRegExp.build('{{h12}} : | {{h24}}', {
27
h12: /1[0-2]|0?[1-9]/,
28
h24: /2[0-3]|[01][0-9]/
29
}, 'x'),
30
minutes: /^[0-5][0-9]$/
31
});
32
33
time.test('10:59'); // true
34
XRegExp.exec('10:59', time).groups.minutes; // '59'
35
36
// Shorthand for named groups: ({{name}}) becomes (?<name>{{name}})
37
const urlPattern = XRegExp.build('({{protocol}})://({{domain}})({{path}})?', {
38
protocol: 'https?',
39
domain: '[\\\\w.-]+',
40
path: '/.*'
41
});
42
```
43
44
### Tag Method
45
46
Creates tagged template literal handler for regex construction with XRegExp syntax.
47
48
```javascript { .api }
49
/**
50
* Creates tagged template literal handler for regex construction
51
* @param flags - Any combination of XRegExp flags
52
* @returns Handler for template literals that construct regexes with XRegExp syntax
53
*/
54
function tag(flags?: string): (literals: TemplateStringsArray, ...substitutions: any[]) => RegExp;
55
```
56
57
**Usage Examples:**
58
59
```javascript
60
// Basic tagged template usage
61
XRegExp.tag()`\\\\b\\\\w+\\\\b`.test('word'); // true
62
63
// With flags and interpolation
64
const hours = /1[0-2]|0?[1-9]/;
65
const minutes = /(?<minutes>[0-5][0-9])/;
66
const time = XRegExp.tag('x')`\\\\b ${hours} : ${minutes} \\\\b`;
67
68
time.test('10:59'); // true
69
XRegExp.exec('10:59', time).groups.minutes; // '59'
70
71
// Backreference rewriting in interpolated regexes
72
const backref1 = /(a)\\\\1/;
73
const backref2 = /(b)\\\\1/;
74
XRegExp.tag()`${backref1}${backref2}`.test('aabb'); // true
75
```
76
77
### Union Method
78
79
Creates union of multiple patterns with backreference renumbering.
80
81
```javascript { .api }
82
/**
83
* Returns XRegExp object that is union of given patterns
84
* @param patterns - Array of regexes and strings to combine
85
* @param flags - Any combination of XRegExp flags
86
* @param options - Options object with conjunction property
87
* @returns Union of the provided regexes and strings
88
*/
89
function union(patterns: (string | RegExp)[], flags?: string, options?: UnionOptions): RegExp;
90
91
interface UnionOptions {
92
conjunction?: 'or' | 'none';
93
}
94
```
95
96
**Usage Examples:**
97
98
```javascript
99
// Standard union with 'or' conjunction
100
XRegExp.union(['a+b*c', /(dogs)\\\\1/, /(cats)\\\\1/], 'i');
101
// Result: /a\\+b\\*c|(dogs)\\1|(cats)\\2/i
102
103
// Concatenation with 'none' conjunction
104
XRegExp.union([/man/, /bear/, /pig/], 'i', {conjunction: 'none'});
105
// Result: /manbearpig/i
106
107
// Mixed patterns with automatic escaping
108
XRegExp.union([
109
'literal.string', // Escaped: literal\\.string
110
/\\d+/, // Used as-is with backreference renumbering
111
'(optional)?' // Escaped: \\(optional\\)\\?
112
], 'g');
113
```
114
115
### Escape Method
116
117
Escapes regex metacharacters for literal matching.
118
119
```javascript { .api }
120
/**
121
* Escapes any regular expression metacharacters for literal string matching
122
* @param str - String to escape
123
* @returns String with regex metacharacters escaped
124
*/
125
function escape(str: string): string;
126
```
127
128
**Usage Examples:**
129
130
```javascript
131
// Basic escaping
132
XRegExp.escape('Escaped? <.>');
133
// Result: 'Escaped\\?\\u0020<\\.>'
134
135
// Safe for use in any regex context
136
const userInput = 'user.input[special]';
137
const literal = XRegExp.escape(userInput);
138
const regex = XRegExp(`start${literal}end`);
139
140
// Useful for building dynamic patterns
141
const searchTerms = ['hello.world', 'test[case]', 'special?chars'];
142
const escapedTerms = searchTerms.map(XRegExp.escape);
143
const pattern = XRegExp.union(escapedTerms, 'gi');
144
```
145
146
## Subpattern Features
147
148
### Named Subpattern Syntax
149
150
The build method supports several subpattern syntaxes:
151
152
```javascript
153
// Basic substitution: {{name}}
154
const basic = XRegExp.build('{{digit}}+', {
155
digit: '\\\\d'
156
});
157
158
// Named group shorthand: ({{name}}) becomes (?<name>{{name}})
159
const named = XRegExp.build('({{year}})-({{month}})', {
160
year: '\\\\d{4}',
161
month: '\\\\d{2}'
162
});
163
// Equivalent to: (?<year>\\d{4})-(?<month>\\d{2})
164
```
165
166
### Automatic Deanchoring
167
168
Leading `^` and trailing `$` are automatically stripped from subpatterns:
169
170
```javascript
171
const pattern = XRegExp.build('start{{middle}}end', {
172
middle: /^\\d+$/ // Anchors are stripped
173
});
174
// Result pattern can match within larger strings
175
```
176
177
### Backreference Renumbering
178
179
Backreferences in subpatterns are automatically renumbered:
180
181
```javascript
182
const pattern = XRegExp.build('{{first}}{{second}}', {
183
first: /(\\w)\\1/, // Uses \\1
184
second: /(\\d)\\1/ // \\1 becomes \\2 in final pattern
185
});
186
// Final pattern handles backreferences correctly
187
```
188
189
## Template Literal Features
190
191
### Raw String Handling
192
193
Template literals handle backslashes as raw strings:
194
195
```javascript
196
// No need to double-escape backslashes
197
const regex1 = XRegExp.tag()`\\d+\\w*`; // Works correctly
198
const regex2 = XRegExp('\\\\d+\\\\w*'); // Equivalent but requires escaping
199
```
200
201
### Interpolation with Type Safety
202
203
Interpolated values are processed safely:
204
205
```javascript
206
// Strings are escaped, regexes preserve structure
207
const userPattern = 'user.input'; // String - will be escaped
208
const numberPattern = /\\d+/; // Regex - used as-is
209
210
const combined = XRegExp.tag()`${userPattern}:${numberPattern}`;
211
// userPattern becomes literal, numberPattern remains regex
212
```
213
214
### Backreference Preservation
215
216
Backreferences in interpolated regexes are rewritten for the combined pattern:
217
218
```javascript
219
const pattern1 = /(.)\\1/; // Matches doubled characters
220
const pattern2 = /(.)\\1/; // Another doubled character pattern
221
222
const combined = XRegExp.tag()`${pattern1}-${pattern2}`;
223
// Backreferences are renumbered: /(.)\\1/-(.)\\2/
224
combined.test('aa-bb'); // true
225
```
226
227
## Advanced Pattern Construction
228
229
### Nested Building
230
231
Build patterns can be nested for complex constructions:
232
233
```javascript
234
const timePattern = XRegExp.build('{{time}}', {
235
time: XRegExp.build('{{hours}}:{{minutes}}', {
236
hours: XRegExp.build('{{h12}}|{{h24}}', {
237
h12: '1[0-2]|0?[1-9]',
238
h24: '2[0-3]|[01][0-9]'
239
}),
240
minutes: '[0-5][0-9]'
241
})
242
});
243
```
244
245
### Mode Modifiers
246
247
Inline mode modifiers affect the entire built pattern:
248
249
```javascript
250
const pattern = XRegExp.build('(?xi) {{spaced}} {{pattern}}', {
251
spaced: 'word1 word2', // Spaces ignored due to x flag
252
pattern: '# This is a comment\\n\\\\d+'
253
});
254
```
255
256
### Dynamic Pattern Generation
257
258
Combine with JavaScript for dynamic pattern creation:
259
260
```javascript
261
function createChoicePattern(choices, flags = '') {
262
const escapedChoices = choices.map(XRegExp.escape);
263
return XRegExp.union(escapedChoices, flags);
264
}
265
266
// Create pattern matching any of the provided options
267
const keywords = ['class', 'function', 'const', 'let'];
268
const keywordPattern = createChoicePattern(keywords, 'gi');
269
```