or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

collection-operations.mdcontent-matching.mdcore-matching.mdindex.mdmatcher-creation.mdregex-compilation.md

regex-compilation.mddocs/

0

# Regex and Compilation

1

2

Low-level pattern parsing, compilation, and regex generation for advanced use cases. These functions provide direct access to nanomatch's internal pattern processing pipeline for custom applications and debugging.

3

4

## Capabilities

5

6

### Regular Expression Generation

7

8

Convert glob patterns directly to regular expressions for use outside nanomatch.

9

10

```javascript { .api }

11

/**

12

* Create a regular expression from a glob pattern

13

* @param {String} pattern - Glob pattern to convert to regular expression

14

* @param {Object} options - Optional configuration for regex compilation

15

* @returns {RegExp} Compiled regular expression that matches the glob pattern

16

*/

17

nanomatch.makeRe(pattern, options);

18

```

19

20

**Usage Examples:**

21

22

```javascript

23

const nanomatch = require('nanomatch');

24

25

// Basic pattern to regex conversion

26

const jsRegex = nanomatch.makeRe('*.js');

27

console.log(jsRegex);

28

//=> /^(?:(?!\.)(?=.)[^\/]*?\.js)$/

29

30

console.log(jsRegex.test('app.js')); //=> true

31

console.log(jsRegex.test('styles.css')); //=> false

32

33

// Globstar patterns

34

const nestedRegex = nanomatch.makeRe('src/**/*.js');

35

console.log(nestedRegex.test('src/app.js')); //=> true

36

console.log(nestedRegex.test('src/components/ui.js')); //=> true

37

console.log(nestedRegex.test('lib/utils.js')); //=> false

38

39

// Question mark patterns

40

const singleCharRegex = nanomatch.makeRe('test?');

41

console.log(singleCharRegex.test('test1')); //=> true

42

console.log(singleCharRegex.test('test')); //=> false

43

console.log(singleCharRegex.test('test12')); //=> false

44

45

// Bracket patterns

46

const bracketRegex = nanomatch.makeRe('[abc]*.js');

47

console.log(bracketRegex.test('app.js')); //=> true

48

console.log(bracketRegex.test('data.js')); //=> false

49

50

// With options

51

const caseInsensitiveRegex = nanomatch.makeRe('*.JS', { nocase: true });

52

console.log(caseInsensitiveRegex.test('app.js')); //=> true

53

54

// Negation patterns

55

const negationRegex = nanomatch.makeRe('!test*');

56

console.log(negationRegex.test('app.js')); //=> true

57

console.log(negationRegex.test('test.js')); //=> false

58

59

// Using with native regex methods

60

const pattern = nanomatch.makeRe('**/*.{js,ts}');

61

const files = ['app.js', 'utils.ts', 'styles.css'];

62

const sourceFiles = files.filter(file => pattern.test(file));

63

console.log(sourceFiles); //=> ['app.js', 'utils.ts']

64

```

65

66

### Complete Pattern Processing

67

68

Parse and compile patterns with full metadata, AST, and compilation details.

69

70

```javascript { .api }

71

/**

72

* Parse and compile a glob pattern with complete metadata

73

* @param {String} pattern - Glob pattern to parse and compile

74

* @param {Object} options - Optional configuration for parsing and compilation

75

* @returns {Object} Complete compilation result with AST, output, and metadata

76

*/

77

nanomatch.create(pattern, options);

78

79

interface CompilationResult {

80

/** Compiled regex pattern string */

81

output: string;

82

/** Parsed abstract syntax tree */

83

ast: ParseResult;

84

/** Source map if sourcemap option enabled */

85

map?: SourceMap;

86

/** Parser options used during compilation */

87

options: Object;

88

/** Parser state information */

89

state: Object;

90

/** Available compiler functions */

91

compilers: Object;

92

}

93

```

94

95

**Usage Examples:**

96

97

```javascript

98

const nanomatch = require('nanomatch');

99

100

// Complete pattern compilation

101

const result = nanomatch.create('src/**/*.js');

102

console.log(result.output);

103

//=> Compiled regex pattern string

104

105

console.log(result.ast);

106

//=> { type: 'root', nodes: [...], input: 'src/**/*.js', ... }

107

108

console.log(result.options);

109

//=> { source: 'string', sourcemap: true, ... }

110

111

// With source map generation

112

const resultWithMap = nanomatch.create('**/*.{js,ts}', { sourcemap: true });

113

console.log(resultWithMap.map);

114

//=> { version: 3, sources: [...], mappings: '...', ... }

115

116

// Complex pattern analysis

117

const complexResult = nanomatch.create('!(**/node_modules|coverage)/**');

118

console.log(complexResult.ast.nodes.length); // Number of AST nodes

119

console.log(complexResult.state); // Parser state information

120

121

// Error analysis

122

const errorResult = nanomatch.create('[invalid');

123

console.log(errorResult.ast.errors); // Array of parsing errors

124

```

125

126

### Pattern Parsing

127

128

Parse glob patterns into abstract syntax trees for analysis and manipulation.

129

130

```javascript { .api }

131

/**

132

* Parse a glob pattern into an abstract syntax tree

133

* @param {String} pattern - Glob pattern string to parse

134

* @param {Object} options - Optional configuration for parsing behavior

135

* @returns {Object} Abstract syntax tree representation of the pattern

136

*/

137

nanomatch.parse(pattern, options);

138

139

interface ParseResult {

140

/** AST root node type */

141

type: string;

142

/** Original input pattern string */

143

input: string;

144

/** Array of child AST nodes */

145

nodes: ASTNode[];

146

/** Array of parsing errors if any */

147

errors: any[];

148

/** Parser instance reference */

149

parser?: Object;

150

}

151

```

152

153

**Usage Examples:**

154

155

```javascript

156

const nanomatch = require('nanomatch');

157

158

// Basic pattern parsing

159

const ast = nanomatch.parse('*.js');

160

console.log(ast);

161

//=> {

162

// type: 'root',

163

// input: '*.js',

164

// nodes: [

165

// { type: 'bos', val: '' },

166

// { type: 'star', val: '*' },

167

// { type: 'text', val: '.js' },

168

// { type: 'eos', val: '' }

169

// ],

170

// errors: []

171

// }

172

173

// Complex pattern parsing

174

const complexAst = nanomatch.parse('src/**/[abc]*.{js,ts}');

175

console.log(complexAst.nodes.map(n => n.type));

176

//=> ['bos', 'text', 'slash', 'globstar', 'slash', 'bracket', 'star', 'text', 'brace', 'eos']

177

178

// Error handling in parsing

179

const invalidAst = nanomatch.parse('[unclosed');

180

console.log(invalidAst.errors.length > 0); //=> true (has parsing errors)

181

182

// Analyze pattern structure

183

function analyzePattern(pattern) {

184

const ast = nanomatch.parse(pattern);

185

const nodeTypes = ast.nodes.map(n => n.type);

186

187

return {

188

hasGlobstar: nodeTypes.includes('globstar'),

189

hasWildcard: nodeTypes.includes('star'),

190

hasBrackets: nodeTypes.includes('bracket'),

191

hasBraces: nodeTypes.includes('brace'),

192

complexity: ast.nodes.length

193

};

194

}

195

196

console.log(analyzePattern('src/**/*.{js,ts}'));

197

//=> { hasGlobstar: true, hasWildcard: true, hasBrackets: false, hasBraces: true, complexity: 9 }

198

```

199

200

### AST Compilation

201

202

Compile abstract syntax trees or pattern strings into regex output.

203

204

```javascript { .api }

205

/**

206

* Compile an AST or pattern string into regex output

207

* @param {Object|String} ast - AST object from parse() or pattern string

208

* @param {Object} options - Optional configuration for compilation behavior

209

* @returns {Object} Compilation result with output pattern and metadata

210

*/

211

nanomatch.compile(ast, options);

212

213

interface CompileResult {

214

/** Compiled regex pattern string */

215

output: string;

216

/** Original or parsed AST */

217

ast: ParseResult;

218

/** Compiler options used */

219

options: Object;

220

/** Compiler state information */

221

state: Object;

222

/** Available compiler functions */

223

compilers: Object;

224

}

225

```

226

227

**Usage Examples:**

228

229

```javascript

230

const nanomatch = require('nanomatch');

231

232

// Compile from string

233

const compiled = nanomatch.compile('*.js');

234

console.log(compiled.output);

235

//=> Compiled regex pattern string

236

237

// Two-step parse and compile

238

const ast = nanomatch.parse('src/**/*.js');

239

const compiled2 = nanomatch.compile(ast);

240

console.log(compiled2.output === nanomatch.create('src/**/*.js').output);

241

//=> true (same output)

242

243

// Compile with custom options

244

const customCompiled = nanomatch.compile('*.JS', { nocase: true });

245

console.log(customCompiled.output); // Case-insensitive regex pattern

246

247

// Access compilation metadata

248

console.log(compiled.state); // Compiler state

249

console.log(compiled.compilers); // Available compiler functions

250

console.log(compiled.options); // Compilation options used

251

252

// Compile modified AST

253

const ast2 = nanomatch.parse('*.js');

254

// Modify AST here if needed

255

const modifiedCompiled = nanomatch.compile(ast2, { dot: true });

256

console.log(modifiedCompiled.output); // Different output due to options

257

```

258

259

## Advanced Usage Patterns

260

261

### Custom Pattern Analysis

262

263

```javascript

264

const nanomatch = require('nanomatch');

265

266

// Pattern complexity analyzer

267

function analyzePatternComplexity(pattern) {

268

const result = nanomatch.create(pattern);

269

const ast = result.ast;

270

271

let complexity = 0;

272

let features = [];

273

274

ast.nodes.forEach(node => {

275

switch (node.type) {

276

case 'star':

277

complexity += 1;

278

features.push('wildcard');

279

break;

280

case 'globstar':

281

complexity += 3;

282

features.push('globstar');

283

break;

284

case 'bracket':

285

complexity += 2;

286

features.push('character-class');

287

break;

288

case 'brace':

289

complexity += 4;

290

features.push('alternation');

291

break;

292

case 'qmark':

293

complexity += 1;

294

features.push('single-char');

295

break;

296

}

297

});

298

299

return {

300

pattern,

301

complexity,

302

features: [...new Set(features)],

303

regexLength: result.output.length,

304

nodeCount: ast.nodes.length

305

};

306

}

307

308

console.log(analyzePatternComplexity('src/**/*.{js,ts,jsx,tsx}'));

309

//=> {

310

// pattern: 'src/**/*.{js,ts,jsx,tsx}',

311

// complexity: 8,

312

// features: ['globstar', 'wildcard', 'alternation'],

313

// regexLength: 89,

314

// nodeCount: 11

315

// }

316

```

317

318

### Pattern Optimization

319

320

```javascript

321

const nanomatch = require('nanomatch');

322

323

// Compare different pattern approaches

324

function comparePatterns(patterns, testStrings) {

325

const results = patterns.map(pattern => {

326

const startTime = process.hrtime.bigint();

327

const regex = nanomatch.makeRe(pattern);

328

const compileTime = process.hrtime.bigint() - startTime;

329

330

const matchStartTime = process.hrtime.bigint();

331

const matches = testStrings.filter(str => regex.test(str));

332

const matchTime = process.hrtime.bigint() - matchStartTime;

333

334

return {

335

pattern,

336

compileTime: Number(compileTime) / 1000000, // Convert to milliseconds

337

matchTime: Number(matchTime) / 1000000,

338

matches: matches.length,

339

regexLength: regex.source.length

340

};

341

});

342

343

return results;

344

}

345

346

const testFiles = [

347

'src/app.js', 'src/utils.ts', 'lib/helper.js',

348

'components/Button.jsx', 'components/List.tsx'

349

];

350

351

const patterns = [

352

'**/*.{js,ts,jsx,tsx}',

353

'**/*.js|**/*.ts|**/*.jsx|**/*.tsx', // Less efficient alternative

354

'{src,lib,components}/**/*.{js,ts,jsx,tsx}'

355

];

356

357

console.log(comparePatterns(patterns, testFiles));

358

// Shows performance comparison between different pattern approaches

359

```

360

361

### Debugging Pattern Compilation

362

363

```javascript

364

const nanomatch = require('nanomatch');

365

366

// Debug pattern compilation step by step

367

function debugPattern(pattern) {

368

console.log(`\nDebugging pattern: ${pattern}`);

369

370

// Step 1: Parse

371

const ast = nanomatch.parse(pattern);

372

console.log('AST nodes:', ast.nodes.map(n => `${n.type}:${n.val || ''}`));

373

374

if (ast.errors.length > 0) {

375

console.log('Parse errors:', ast.errors);

376

}

377

378

// Step 2: Compile

379

const compiled = nanomatch.compile(ast);

380

console.log('Compiled output:', compiled.output);

381

382

// Step 3: Create regex

383

const regex = nanomatch.makeRe(pattern);

384

console.log('Final regex:', regex);

385

console.log('Regex source:', regex.source);

386

387

// Step 4: Test cases

388

const testCases = ['app.js', 'src/app.js', 'test.txt', '.hidden.js'];

389

console.log('Test results:');

390

testCases.forEach(test => {

391

console.log(` ${test}: ${regex.test(test)}`);

392

});

393

}

394

395

debugPattern('src/**/*.js');

396

debugPattern('*.{js,ts}');

397

debugPattern('[abc]*.js');

398

```

399

400

## Error Handling and Edge Cases

401

402

```javascript

403

const nanomatch = require('nanomatch');

404

405

// Pattern length limits

406

try {

407

const longPattern = '*'.repeat(70000); // Exceeds MAX_LENGTH

408

nanomatch.makeRe(longPattern);

409

} catch (error) {

410

console.log(error.message);

411

//=> 'expected pattern to be less than 65536 characters'

412

}

413

414

// Invalid pattern types

415

try {

416

nanomatch.makeRe(123);

417

} catch (error) {

418

console.log(error.message);

419

//=> 'expected pattern to be a string'

420

}

421

422

try {

423

nanomatch.parse(null);

424

} catch (error) {

425

console.log(error.message);

426

//=> 'expected a string'

427

}

428

429

// RegExp input handling

430

const existingRegex = /\.js$/;

431

const passThrough = nanomatch.makeRe(existingRegex);

432

console.log(passThrough === existingRegex); //=> true (returns as-is)

433

434

// Empty pattern handling

435

const emptyRegex = nanomatch.makeRe('');

436

console.log(emptyRegex.test('anything')); //=> false

437

438

// Malformed bracket patterns

439

const malformedResult = nanomatch.create('[unclosed');

440

console.log(malformedResult.ast.errors.length > 0); //=> true

441

```

442

443

## Performance and Memory Considerations

444

445

- `makeRe()` results are cached - identical patterns return the same RegExp instance

446

- `create()`, `parse()`, and `compile()` also benefit from caching

447

- ASTs can be large for complex patterns - consider memory usage for many patterns

448

- `create()` with `sourcemap: true` uses additional memory for source map data

449

- For simple use cases, higher-level functions like `isMatch()` are more efficient

450

- Direct regex compilation is fastest when you need to test the same pattern many times