1 | # micromatch [![NPM version](https://badge.fury.io/js/micromatch.svg)](http://badge.fury.io/js/micromatch) [![Build Status](https://travis-ci.org/jonschlinkert/micromatch.svg)](https://travis-ci.org/jonschlinkert/micromatch)
|
2 |
|
3 | > Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just use `micromatch.isMatch()` instead of `minimatch()`, or use `micromatch()` instead of `multimatch()`.
|
4 |
|
5 | ## Features
|
6 |
|
7 | Micromatch is [10-55x faster](#benchmarks) than [minimatch], resulting from a combination of caching, tokenization, parsing, runtime compilation and regex optimization strategies.
|
8 |
|
9 | - [Drop-in replacement][switch] for [minimatch] and [multimatch]
|
10 | - Built-in support for multiple glob patterns, like `['foo/*.js', '!bar.js']`
|
11 | - Better support for the Bash 4.3 specification, and less buggy
|
12 | - Extensive [unit tests](./test) (approx. 1,300 tests). Minimatch fails many of the tests.
|
13 |
|
14 | **Supports**
|
15 |
|
16 | Mainstream glob features:
|
17 |
|
18 | + [Brace Expansion][braces] (`foo/bar-{1..5}.md`, `one/{two,three}/four.md`)
|
19 | + Typical glob patterns, like `**/*`, `a/b/*.js`, or `['foo/*.js', '!bar.js']`
|
20 |
|
21 | Extended globbing features:
|
22 |
|
23 | + Logical `OR` (`foo/bar/(abc|xyz).js`)
|
24 | + Regex character classes (`foo/bar/baz-[1-5].js`)
|
25 | + POSIX bracket expressions (`**/[[:alpha:][:digit:]]/`)
|
26 | + extglobs (`**/+(x|y)`, `!(a|b)`, etc)
|
27 |
|
28 | You can combine these to create whatever matching patterns you need.
|
29 |
|
30 | ## Install with [npm](npmjs.org)
|
31 |
|
32 | ```bash
|
33 | npm i micromatch --save
|
34 | ```
|
35 |
|
36 | ## Usage
|
37 |
|
38 | ```js
|
39 | var mm = require('micromatch');
|
40 | mm(array, patterns);
|
41 | ```
|
42 |
|
43 | **Examples**
|
44 |
|
45 | ```js
|
46 | mm(['a.js', 'b.md', 'c.txt'], '*.{js,txt}');
|
47 | //=> ['a.js', 'c.txt']
|
48 | ```
|
49 |
|
50 | **Multiple patterns**
|
51 |
|
52 | Multiple patterns can also be passed:
|
53 |
|
54 | ```js
|
55 | mm(['a.md', 'b.js', 'c.txt', 'd.json'], ['*.md', '*.txt']);
|
56 | //=> ['a.md', 'c.txt']
|
57 | ```
|
58 |
|
59 | **Negation patterns:**
|
60 |
|
61 | ```js
|
62 | mm(['a.js', 'b.md', 'c.txt'], '!*.{js,txt}');
|
63 | //=> ['b.md']
|
64 |
|
65 | mm(['a.md', 'b.js', 'c.txt', 'd.json'], ['*.*', '!*.{js,txt}']);
|
66 | //=> ['a.md', 'd.json']
|
67 | ```
|
68 |
|
69 | ## Switch from minimatch
|
70 |
|
71 | > Use `micromatch.isMatch()` instead of `minimatch()`
|
72 |
|
73 | **Minimatch**
|
74 |
|
75 | The main `minimatch()` function returns true/false for a single file path and pattern:
|
76 |
|
77 | ```js
|
78 | var minimatch = require('minimatch');
|
79 | minimatch('foo.js', '*.js');
|
80 | //=> 'true'
|
81 | ```
|
82 |
|
83 | **Micromatch**
|
84 |
|
85 | Use `.isMatch()` to get the same result:
|
86 |
|
87 |
|
88 | ```js
|
89 | var mm = require('micromatch');
|
90 | mm.isMatch('foo.js', '*.js');
|
91 | //=> 'true'
|
92 | ```
|
93 |
|
94 | This implementation difference is necessary since the main `micromatch()` method supports matching on multiple globs, with behavior similar to [multimatch].
|
95 |
|
96 |
|
97 | ## Methods
|
98 |
|
99 | ```js
|
100 | var mm = require('micromatch');
|
101 | ```
|
102 |
|
103 | ### .isMatch
|
104 |
|
105 | ```js
|
106 | mm.isMatch(filepath, globPattern);
|
107 | ```
|
108 |
|
109 | Returns true if a file path matches the given glob pattern.
|
110 |
|
111 |
|
112 | **Example**
|
113 |
|
114 | ```js
|
115 | mm.isMatch('.verb.md', '*.md');
|
116 | //=> false
|
117 |
|
118 | mm.isMatch('.verb.md', '*.md', {dot: true});
|
119 | //=> true
|
120 | ```
|
121 |
|
122 | ### .contains
|
123 |
|
124 | Returns true if any part of a file path matches the given glob pattern. Think of this is "has path" versus "is path".
|
125 |
|
126 | **Example**
|
127 |
|
128 | `.isMatch()` would return false for both of the following:
|
129 |
|
130 | ```js
|
131 | mm.contains('a/b/c', 'a/b');
|
132 | //=> true
|
133 |
|
134 | mm.contains('a/b/c', 'a/*');
|
135 | //=> true
|
136 | ```
|
137 |
|
138 | ### .matcher
|
139 |
|
140 | Returns a function for matching using the supplied pattern. e.g. create your own "matcher". The advantage of this method is that the pattern can be compiled outside of a loop.
|
141 |
|
142 | **Pattern**
|
143 |
|
144 | Can be any of the following:
|
145 |
|
146 | - `glob/string`
|
147 | - `regex`
|
148 | - `function`
|
149 |
|
150 | **Example**
|
151 |
|
152 | ```js
|
153 | var isMatch = mm.matcher('*.md');
|
154 | var files = [];
|
155 |
|
156 | ['a.md', 'b.txt', 'c.md'].forEach(function(fp) {
|
157 | if (isMatch(fp)) {
|
158 | files.push(fp);
|
159 | }
|
160 | });
|
161 | ```
|
162 |
|
163 | ### .filter
|
164 |
|
165 | Returns a function that can be passed to `Array#filter()`.
|
166 |
|
167 | **Params**
|
168 |
|
169 | - `patterns` **{String|Array}**:
|
170 |
|
171 | **Examples**
|
172 |
|
173 | Single glob:
|
174 |
|
175 | ```js
|
176 | var fn = mm.filter('*.md');
|
177 | ['a.js', 'b.txt', 'c.md'].filter(fn);
|
178 | //=> ['c.md']
|
179 |
|
180 | var fn = mm.filter('[a-c]');
|
181 | ['a', 'b', 'c', 'd', 'e'].filter(fn);
|
182 | //=> ['a', 'b', 'c']
|
183 | ```
|
184 |
|
185 | Array of glob patterns:
|
186 |
|
187 | ```js
|
188 | var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
|
189 |
|
190 | var fn = mm.filter(['{1..10}', '![7-9]', '!{3..4}']);
|
191 | arr.filter(fn);
|
192 | //=> [1, 2, 5, 6, 10]
|
193 | ```
|
194 |
|
195 | _(Internally this function generates the matching function by using the [matcher] method. You can use the [matcher] method directly to create your own filter function)_
|
196 |
|
197 |
|
198 | ### .any
|
199 |
|
200 | Returns true if a file path matches any of the given patterns.
|
201 |
|
202 | ```js
|
203 | mm.any(filepath, patterns, options);
|
204 | ```
|
205 |
|
206 | **Params**
|
207 |
|
208 | - filepath `{String}`: The file path to test.
|
209 | - patterns `{String|Array}`: One or more glob patterns
|
210 | - options: `{Object}`: options to pass to the `.matcher()` method.
|
211 |
|
212 |
|
213 | **Example**
|
214 |
|
215 | ```js
|
216 | mm.any('abc', ['!*z']);
|
217 | //=> true
|
218 | mm.any('abc', ['a*', 'z*']);
|
219 | //=> true
|
220 | mm.any('abc', 'a*');
|
221 | //=> true
|
222 | mm.any('abc', ['z*']);
|
223 | //=> false
|
224 | ```
|
225 |
|
226 |
|
227 | ### .expand
|
228 |
|
229 | Returns an object with a regex-compatible string and tokens.
|
230 |
|
231 | ```js
|
232 | mm.expand('*.js');
|
233 |
|
234 | // when `track` is enabled (for debugging), the `history` array is used
|
235 | // to record each mutation to the glob pattern as it's converted to regex
|
236 | { options: { track: false, dot: undefined, makeRe: true, negated: false },
|
237 | pattern: '(.*\\/|^)bar\\/(?:(?!(?:^|\\/)\\.).)*?',
|
238 | history: [],
|
239 | tokens:
|
240 | { path:
|
241 | { whole: '**/bar/**',
|
242 | dirname: '**/bar/',
|
243 | filename: '**',
|
244 | basename: '**',
|
245 | extname: '',
|
246 | ext: '' },
|
247 | is:
|
248 | { glob: true,
|
249 | negated: false,
|
250 | globstar: true,
|
251 | dotfile: false,
|
252 | dotdir: false },
|
253 | match: {},
|
254 | original: '**/bar/**',
|
255 | pattern: '**/bar/**',
|
256 | base: '' } }
|
257 | ```
|
258 |
|
259 | ### .makeRe
|
260 |
|
261 | Create a regular expression for matching file paths based on the given pattern:
|
262 |
|
263 | ```js
|
264 | mm.makeRe('*.js');
|
265 | //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
|
266 | ```
|
267 |
|
268 | ## Options
|
269 |
|
270 | All options should work the same way as [minimatch].
|
271 |
|
272 | ### options.dot
|
273 |
|
274 | Match dotfiles.
|
275 |
|
276 | Type: `{Boolean}`
|
277 |
|
278 | Default: `false`
|
279 |
|
280 |
|
281 | ### options.matchBase
|
282 |
|
283 | Allow glob patterns without slashes to match a file path based on its basename.
|
284 |
|
285 | Type: `{Boolean}`
|
286 |
|
287 | Default: `false`
|
288 |
|
289 | **Example**
|
290 |
|
291 | ```js
|
292 | mm(['a/b.js', 'a/c.md'], '*.js');
|
293 | //=> []
|
294 |
|
295 | mm(['a/b.js', 'a/c.md'], '*.js', {matchBase: true});
|
296 | //=> ['a/b.js']
|
297 | ```
|
298 |
|
299 | ### options.nobraces
|
300 |
|
301 | Don't expand braces in glob patterns.
|
302 |
|
303 | Type: `{Boolean}`
|
304 |
|
305 | Default: `false`
|
306 |
|
307 |
|
308 | ### options.nocase
|
309 |
|
310 | Use a case-insensitive regex for matching files.
|
311 |
|
312 | Type: `{Boolean}`
|
313 |
|
314 | Default: `false`
|
315 |
|
316 |
|
317 | ### options.nonull
|
318 |
|
319 | If `true`, when no matches are found the actual (array-ified) glob pattern is returned instead of an empty array.
|
320 |
|
321 | Type: `{Boolean}`
|
322 |
|
323 | Default: `false`
|
324 |
|
325 |
|
326 | ### options.cache
|
327 |
|
328 | Cache the platform (e.g. `win32`) to prevent this from being looked up for every fil.
|
329 |
|
330 | Type: `{Boolean}`
|
331 |
|
332 | Default: `true`
|
333 |
|
334 |
|
335 | ## Other features
|
336 |
|
337 | Micromatch also supports the following.
|
338 |
|
339 | ### Extended globbing
|
340 |
|
341 | Extended globbing as described by the bash man page:
|
342 |
|
343 | | **pattern** | **regex equivalent** | **description** |
|
344 | | --- | --- | --- |
|
345 | | `?(pattern-list)` | `(...|...)?` | Matches zero or one occurrence of the given patterns |
|
346 | | `*(pattern-list)` | `(...|...)*` | Matches zero or more occurrences of the given patterns |
|
347 | | `+(pattern-list)` | `(...|...)+` | Matches one or more occurrences of the given patterns |
|
348 | | `@(pattern-list)` | `(...|...)` <sup>*</sup> | Matches one of the given patterns |
|
349 | | `!(pattern-list)` | N/A | Matches anything except one of the given patterns |
|
350 |
|
351 | <sup><strong>*</strong></sup> `@` isn't a RegEx character.
|
352 |
|
353 |
|
354 | ### Brace Expansion
|
355 |
|
356 | In simple cases, brace expansion appears to work the same way as the logical `OR` operator. For example, `(a|b)` will achieve the same result as `{a,b}`.
|
357 |
|
358 | Here are some powerful features unique to brace expansion (versus character classes):
|
359 |
|
360 | - range expansion: `a{1..3}b/*.js` expands to: `['a1b/*.js', 'a2b/*.js', 'a3b/*.js']`
|
361 | - nesting: `a{c,{d,e}}b/*.js` expands to: `['acb/*.js', 'adb/*.js', 'aeb/*.js']`
|
362 |
|
363 |
|
364 | Learn about [brace expansion][braces], or visit [braces][braces] to ask questions and create an issue related to brace-expansion, or to see the full range of features and options related to brace expansion.
|
365 |
|
366 |
|
367 | ### Regex character classes
|
368 |
|
369 | With the exception of brace expansion (`{a,b}`, `{1..5}`, etc), most of the special characters convert directly to regex, so you can expect them to follow the same rules and produce the same results as regex.
|
370 |
|
371 | For example, given the list: `['a.js', 'b.js', 'c.js', 'd.js', 'E.js']`:
|
372 |
|
373 | - `[ac].js`: matches both `a` and `c`, returning `['a.js', 'c.js']`
|
374 | - `[b-d].js`: matches from `b` to `d`, returning `['b.js', 'c.js', 'd.js']`
|
375 | - `[b-d].js`: matches from `b` to `d`, returning `['b.js', 'c.js', 'd.js']`
|
376 | - `a/[A-Z].js`: matches and uppercase letter, returning `['a/E.md']`
|
377 |
|
378 | Learn about [regex character classes][character-classes].
|
379 |
|
380 | ### Regex groups
|
381 |
|
382 | Given `['a.js', 'b.js', 'c.js', 'd.js', 'E.js']`:
|
383 |
|
384 | - `(a|c).js`: would match either `a` or `c`, returning `['a.js', 'c.js']`
|
385 | - `(b|d).js`: would match either `b` or `d`, returning `['b.js', 'd.js']`
|
386 | - `(b|[A-Z]).js`: would match either `b` or an uppercase letter, returning `['b.js', 'E.js']`
|
387 |
|
388 | As with regex, parenthese can be nested, so patterns like `((a|b)|c)/b` will work. But it might be easier to achieve your goal using brace expansion.
|
389 |
|
390 | ## Notes
|
391 |
|
392 | Whenever possible parsing behavior for patterns is based on globbing specifications in Bash 4.3. Patterns that aren't described by Bash follow wildmatch spec (used by git).
|
393 |
|
394 |
|
395 | ## Benchmarks
|
396 |
|
397 | Run the [benchmarks](./benchmark):
|
398 |
|
399 | ```bash
|
400 | npm run benchmark
|
401 | ```
|
402 |
|
403 | As of March 27, 2015:
|
404 |
|
405 | ```bash
|
406 | #1: basename-braces
|
407 | micromatch x 27,734 ops/sec ±0.75% (93 runs sampled)
|
408 | minimatch x 3,409 ops/sec ±0.77% (97 runs sampled)
|
409 |
|
410 | #2: basename
|
411 | micromatch x 26,727 ops/sec ±0.81% (97 runs sampled)
|
412 | minimatch x 4,122 ops/sec ±0.77% (97 runs sampled)
|
413 |
|
414 | #3: braces-no-glob
|
415 | micromatch x 324,367 ops/sec ±0.62% (95 runs sampled)
|
416 | minimatch x 29,682 ops/sec ±0.71% (94 runs sampled)
|
417 |
|
418 | #4: braces
|
419 | micromatch x 63,430 ops/sec ±1.14% (95 runs sampled)
|
420 | minimatch x 2,749 ops/sec ±0.77% (97 runs sampled)
|
421 |
|
422 | #5: immediate
|
423 | micromatch x 21,842 ops/sec ±0.66% (98 runs sampled)
|
424 | minimatch x 3,638 ops/sec ±0.66% (97 runs sampled)
|
425 |
|
426 | #6: large
|
427 | micromatch x 802 ops/sec ±0.58% (96 runs sampled)
|
428 | minimatch x 15.72 ops/sec ±1.25% (42 runs sampled)
|
429 |
|
430 | #7: long
|
431 | micromatch x 8,061 ops/sec ±0.69% (96 runs sampled)
|
432 | minimatch x 560 ops/sec ±0.71% (90 runs sampled)
|
433 |
|
434 | #8: mid
|
435 | micromatch x 67,972 ops/sec ±0.78% (93 runs sampled)
|
436 | minimatch x 1,745 ops/sec ±0.87% (96 runs sampled)
|
437 |
|
438 | #9: multi-patterns
|
439 | micromatch x 25,136 ops/sec ±0.87% (95 runs sampled)
|
440 | minimatch x 1,986 ops/sec ±1.03% (95 runs sampled)
|
441 |
|
442 | #10: no-glob
|
443 | micromatch x 1,062,274 ops/sec ±0.90% (94 runs sampled)
|
444 | minimatch x 53,150 ops/sec ±0.85% (96 runs sampled)
|
445 |
|
446 | #11: range
|
447 | micromatch x 270,918 ops/sec ±0.75% (97 runs sampled)
|
448 | minimatch x 13,548 ops/sec ±0.85% (96 runs sampled)
|
449 |
|
450 | #12: shallow
|
451 | micromatch x 198,022 ops/sec ±0.80% (97 runs sampled)
|
452 | minimatch x 20,093 ops/sec ±0.62% (95 runs sampled)
|
453 |
|
454 | #13: short
|
455 | micromatch x 440,230 ops/sec ±0.84% (97 runs sampled)
|
456 | minimatch x 58,116 ops/sec ±0.74% (92 runs sampled)
|
457 |
|
458 | ```
|
459 |
|
460 | ## Run tests
|
461 | Install dev dependencies:
|
462 |
|
463 | ```bash
|
464 | npm i -d && npm test
|
465 | ```
|
466 |
|
467 | ## Contributing
|
468 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/micromatch/issues)
|
469 |
|
470 | Please be sure to run the benchmarks before/after any code changes to judge the impact before you do a PR. thanks!
|
471 |
|
472 | ## Related
|
473 | * [braces](https://github.com/jonschlinkert/braces): Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification.
|
474 | * [fill-range](https://github.com/jonschlinkert/fill-range): Fill in a range of numbers or letters, optionally passing an increment or multiplier to use.
|
475 | * [expand-range](https://github.com/jonschlinkert/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See the benchmarks. Used by micromatch.
|
476 | * [parse-glob](https://github.com/jonschlinkert/parse-glob): Parse a glob pattern into an object of tokens.
|
477 | * [is-glob](https://github.com/jonschlinkert/is-glob): Returns `true` if the given string looks like a glob pattern.
|
478 |
|
479 | ## Author
|
480 |
|
481 | **Jon Schlinkert**
|
482 |
|
483 | + [github/jonschlinkert](https://github.com/jonschlinkert)
|
484 | + [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
485 |
|
486 | ## License
|
487 | Copyright (c) 2014-2015 Jon Schlinkert
|
488 | Released under the MIT license
|
489 |
|
490 | ***
|
491 |
|
492 | _This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 27, 2015._
|
493 |
|
494 | [switch]: #switch-from-minimatch
|
495 | [multimatch]: https://github.com/sindresorhus/multimatch
|
496 | [minimatch]: https://github.com/isaacs/minimatch
|
497 | [brace expansion]: https://github.com/jonschlinkert/braces
|
498 | [braces]: https://github.com/jonschlinkert/braces
|
499 | [bracket expressions]: https://github.com/jonschlinkert/expand-brackets
|
500 | [character-classes]: http://www.regular-expressions.info/charclass.html
|
501 | [expand]: https://github.com/jonschlinkert/micromatch#expand
|
502 | [extended]: http://mywiki.wooledge.org/BashGuide/Patterns#Extended_Globs
|
503 | [extglobs]: https://github.com/jonschlinkert/extglob
|
504 |
|