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 faster alternative to minimatch (10-45x faster on avg), with all the features you're used to using in your Grunt and gulp tasks.
|
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 |
|
15 | **Supports**
|
16 |
|
17 | Mainstream glob features:
|
18 |
|
19 | + [Brace Expansion][braces] (`foo/bar-{1..5}.md`, `one/{two,three}/four.md`)
|
20 | + Typical glob patterns, like `**/*`, `a/b/*.js`, or `['foo/*.js', '!bar.js']`
|
21 |
|
22 | Extended globbing features:
|
23 |
|
24 | + Logical `OR` (`foo/bar/(abc|xyz).js`)
|
25 | + Regex character classes (`foo/bar/baz-[1-5].js`)
|
26 | + POSIX bracket expressions (`**/[[:alpha:][:digit:]]/`)
|
27 | + extglobs (`**/+(x|y)`, `!(a|b)`, etc)
|
28 |
|
29 | You can combine these to create whatever matching patterns you need.
|
30 |
|
31 |
|
32 | ## Install with [npm](npmjs.org)
|
33 |
|
34 | ```bash
|
35 | npm i micromatch --save
|
36 | ```
|
37 |
|
38 |
|
39 | ## Usage
|
40 |
|
41 | ```js
|
42 | var mm = require('micromatch');
|
43 | mm(array, patterns);
|
44 | ```
|
45 |
|
46 | **Examples**
|
47 |
|
48 | ```js
|
49 | mm(['a.js', 'b.md', 'c.txt'], '*.{js,txt}');
|
50 | //=> ['a.js', 'c.txt']
|
51 | ```
|
52 |
|
53 | **Multiple patterns**
|
54 |
|
55 | Multiple patterns can also be passed:
|
56 |
|
57 | ```js
|
58 | mm(['a.md', 'b.js', 'c.txt', 'd.json'], ['*.md', '*.txt']);
|
59 | //=> ['a.md', 'c.txt']
|
60 | ```
|
61 |
|
62 | **Negation patterns:**
|
63 |
|
64 | ```js
|
65 | mm(['a.js', 'b.md', 'c.txt'], '!*.{js,txt}');
|
66 | //=> ['b.md']
|
67 |
|
68 | mm(['a.md', 'b.js', 'c.txt', 'd.json'], ['*.*', '!*.{js,txt}']);
|
69 | //=> ['a.md', 'd.json']
|
70 | ```
|
71 |
|
72 | ## Switch from minimatch
|
73 |
|
74 | > Use `micromatch.isMatch()` instead of `minimatch()`
|
75 |
|
76 | **Minimatch**
|
77 |
|
78 | The main `minimatch()` function returns true/false for a single file path and pattern:
|
79 |
|
80 | ```js
|
81 | var minimatch = require('minimatch');
|
82 | minimatch('foo.js', '*.js');
|
83 | //=> 'true'
|
84 | ```
|
85 |
|
86 | **Micromatch**
|
87 |
|
88 | Use `.isMatch()` to get the same result:
|
89 |
|
90 |
|
91 | ```js
|
92 | var mm = require('micromatch');
|
93 | mm.isMatch('foo.js', '*.js');
|
94 | //=> 'true'
|
95 | ```
|
96 |
|
97 | This implementation difference is necessary since the main `micromatch()` method supports matching on multiple globs, with behavior similar to [multimatch].
|
98 |
|
99 |
|
100 | ## Methods
|
101 |
|
102 | ```js
|
103 | var mm = require('micromatch');
|
104 | ```
|
105 |
|
106 | ### .isMatch
|
107 |
|
108 | ```js
|
109 | mm.isMatch(filepath, globPattern);
|
110 | ```
|
111 |
|
112 | Returns true if a file path matches the given glob pattern.
|
113 |
|
114 |
|
115 | **Example**
|
116 |
|
117 | ```js
|
118 | mm.isMatch('.verb.md', '*.md');
|
119 | //=> false
|
120 |
|
121 | mm.isMatch('.verb.md', '*.md', {dot: true});
|
122 | //=> true
|
123 | ```
|
124 |
|
125 | ### .contains
|
126 |
|
127 | Returns true if any part of a file path match the given glob pattern. Think of this is "has path" versus "is path".
|
128 |
|
129 | **Example**
|
130 |
|
131 | `.isMatch()` would return false for both of the following:
|
132 |
|
133 | ```js
|
134 | mm.contains('a/b/c', 'a/b');
|
135 | //=> true
|
136 |
|
137 | mm.contains('a/b/c', 'a/*');
|
138 | //=> true
|
139 | ```
|
140 |
|
141 | ### .matcher
|
142 |
|
143 | 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.
|
144 |
|
145 | **Pattern**
|
146 |
|
147 | Can be any of the following:
|
148 |
|
149 | - `glob/string`
|
150 | - `regex`
|
151 | - `function`
|
152 |
|
153 | **Example**
|
154 |
|
155 | ```js
|
156 | var isMatch = mm.matcher('*.md');
|
157 | var files = [];
|
158 |
|
159 | ['a.md', 'b.txt', 'c.md'].forEach(function(fp) {
|
160 | if (isMatch(fp)) {
|
161 | files.push(fp);
|
162 | }
|
163 | });
|
164 | ```
|
165 |
|
166 | ### .filter
|
167 |
|
168 | Returns a function that can be passed to `Array#filter()`.
|
169 |
|
170 | **Params**
|
171 |
|
172 | - `patterns` **{String|Array}**:
|
173 |
|
174 | **Examples**
|
175 |
|
176 | Single glob:
|
177 |
|
178 | ```js
|
179 | var fn = mm.filter('*.md');
|
180 | ['a.js', 'b.txt', 'c.md'].filter(fn);
|
181 | //=> ['c.md']
|
182 |
|
183 | var fn = mm.filter('[a-c]');
|
184 | ['a', 'b', 'c', 'd', 'e'].filter(fn);
|
185 | //=> ['a', 'b', 'c']
|
186 | ```
|
187 |
|
188 | Array of glob patterns:
|
189 |
|
190 | ```js
|
191 | var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
|
192 |
|
193 | var fn = mm.filter(['{1..10}', '![7-9]', '!{3..4}']);
|
194 | arr.filter(fn);
|
195 | //=> [1, 2, 5, 6, 10]
|
196 | ```
|
197 |
|
198 | _(Internally this function generates the matching function using the [matcher] method. You can use the [matcher] method directly to create your own filter function)_
|
199 |
|
200 |
|
201 | ### .any
|
202 |
|
203 | Returns true if a file path matches any of the given patterns.
|
204 |
|
205 | ```js
|
206 | mm.any(filepath, patterns, options);
|
207 | ```
|
208 |
|
209 | **Params**
|
210 |
|
211 | - filepath `{String}`: The file path to test.
|
212 | - patterns `{String|Array}`: One or more glob patterns
|
213 | - options: `{Object}`: options to pass to the `.matcher()` method.
|
214 |
|
215 |
|
216 | **Example**
|
217 |
|
218 | ```js
|
219 | mm.any('abc', ['!*z']);
|
220 | //=> true
|
221 | mm.any('abc', ['a*', 'z*']);
|
222 | //=> true
|
223 | mm.any('abc', 'a*');
|
224 | //=> true
|
225 | mm.any('abc', ['z*']);
|
226 | //=> false
|
227 | ```
|
228 |
|
229 |
|
230 | ### .expand
|
231 |
|
232 | Returns an object with a regex-compatible string and tokens.
|
233 |
|
234 | ```js
|
235 | mm.expand('*.js');
|
236 |
|
237 | // when `track` is enabled (for debugging), the `history` array is used
|
238 | // to record each mutation to the glob pattern as it's converted to regex
|
239 | { options: { track: false, dot: undefined, makeRe: true, negated: false },
|
240 | pattern: '(.*\\/|^)bar\\/(?:(?!(?:^|\\/)\\.).)*?',
|
241 | history: [],
|
242 | tokens:
|
243 | { path:
|
244 | { whole: '**/bar/**',
|
245 | dirname: '**/bar/',
|
246 | filename: '**',
|
247 | basename: '**',
|
248 | extname: '',
|
249 | ext: '' },
|
250 | is:
|
251 | { glob: true,
|
252 | negated: false,
|
253 | globstar: true,
|
254 | dotfile: false,
|
255 | dotdir: false },
|
256 | match: {},
|
257 | original: '**/bar/**',
|
258 | pattern: '**/bar/**',
|
259 | base: '' } }
|
260 | ```
|
261 |
|
262 | ### .makeRe
|
263 |
|
264 | Create a regular expression for matching file paths based on the given pattern:
|
265 |
|
266 | ```js
|
267 | mm.makeRe('*.js');
|
268 | //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
|
269 | ```
|
270 |
|
271 | ## Options
|
272 |
|
273 | All options should work the same way as [minimatch].
|
274 |
|
275 | ### options.dot
|
276 |
|
277 | Match dotfiles.
|
278 |
|
279 | Type: `{Boolean}`
|
280 |
|
281 | Default: `false`
|
282 |
|
283 |
|
284 | ### options.matchBase
|
285 |
|
286 | Allow glob patterns without slashes to match a file path based on its basename.
|
287 |
|
288 | Type: `{Boolean}`
|
289 |
|
290 | Default: `false`
|
291 |
|
292 | **Example**
|
293 |
|
294 | ```js
|
295 | mm(['a/b.js', 'a/c.md'], '*.js');
|
296 | //=> []
|
297 |
|
298 | mm(['a/b.js', 'a/c.md'], '*.js', {matchBase: true});
|
299 | //=> ['a/b.js']
|
300 | ```
|
301 |
|
302 | ### options.nobraces
|
303 |
|
304 | Don't expand braces in glob patterns.
|
305 |
|
306 | Type: `{Boolean}`
|
307 |
|
308 | Default: `false`
|
309 |
|
310 |
|
311 | ### options.nocase
|
312 |
|
313 | Use a case-insensitive regex for matching files.
|
314 |
|
315 | Type: `{Boolean}`
|
316 |
|
317 | Default: `false`
|
318 |
|
319 |
|
320 | ### options.nonull
|
321 |
|
322 | If `true`, when no matches are found the actual (array-ified) glob pattern is returned instead of an empty array.
|
323 |
|
324 | Type: `{Boolean}`
|
325 |
|
326 | Default: `false`
|
327 |
|
328 |
|
329 | ### options.cache
|
330 |
|
331 | Cache the platform (e.g. `win32`) to prevent this from being looked up for every fil.
|
332 |
|
333 | Type: `{Boolean}`
|
334 |
|
335 | Default: `true`
|
336 |
|
337 |
|
338 | ## Other features
|
339 |
|
340 | Micromatch also supports the following.
|
341 |
|
342 | ### Extended globbing
|
343 |
|
344 | Extended globbing as described by the bash man page:
|
345 |
|
346 | | **pattern** | **regex equivalent** | **description** |
|
347 | | --- | --- |
|
348 | | `?(pattern-list)` | `(...|...)?` | Matches zero or one occurrence of the given patterns |
|
349 | | `*(pattern-list)` | `(...|...)*` | Matches zero or more occurrences of the given patterns |
|
350 | | `+(pattern-list)` | `(...|...)+` | Matches one or more occurrences of the given patterns |
|
351 | | `@(pattern-list)` | `(...|...)` <sup>*</sup> | Matches one of the given patterns |
|
352 | | `!(pattern-list)` | N/A | Matches anything except one of the given patterns |
|
353 |
|
354 | <sup><strong>*</strong></sup> `@` isn't a RegEx character.
|
355 |
|
356 |
|
357 | ### Brace Expansion
|
358 |
|
359 | 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}`.
|
360 |
|
361 | Here are some powerful features unique to brace expansion (versus character classes):
|
362 |
|
363 | - range expansion: `a{1..3}b/*.js` expands to: `['a1b/*.js', 'a2b/*.js', 'a3b/*.js']`
|
364 | - nesting: `a{c,{d,e}}b/*.js` expands to: `['acb/*.js', 'adb/*.js', 'aeb/*.js']`
|
365 |
|
366 |
|
367 | 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.
|
368 |
|
369 |
|
370 | ### Regex character classes
|
371 |
|
372 | 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.
|
373 |
|
374 | For example, given the list: `['a.js', 'b.js', 'c.js', 'd.js', 'E.js']`:
|
375 |
|
376 | - `[ac].js`: matches both `a` and `c`, returning `['a.js', 'c.js']`
|
377 | - `[b-d].js`: matches from `b` to `d`, returning `['b.js', 'c.js', 'd.js']`
|
378 | - `[b-d].js`: matches from `b` to `d`, returning `['b.js', 'c.js', 'd.js']`
|
379 | - `a/[A-Z].js`: matches and uppercase letter, returning `['a/E.md']`
|
380 |
|
381 | Learn about [regex character classes][character-classes].
|
382 |
|
383 | ### Regex groups
|
384 |
|
385 | Given `['a.js', 'b.js', 'c.js', 'd.js', 'E.js']`:
|
386 |
|
387 | - `(a|c).js`: would match either `a` or `c`, returning `['a.js', 'c.js']`
|
388 | - `(b|d).js`: would match either `b` or `d`, returning `['b.js', 'd.js']`
|
389 | - `(b|[A-Z]).js`: would match either `b` or an uppercase letter, returning `['b.js', 'E.js']`
|
390 |
|
391 | 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.
|
392 |
|
393 |
|
394 | ## Benchmarks
|
395 |
|
396 | Run the [benchmarks](./benchmark):
|
397 |
|
398 | ```bash
|
399 | npm run benchmark
|
400 | ```
|
401 |
|
402 | As of March 06, 2015:
|
403 |
|
404 | ```bash
|
405 | #1: basename-braces.js
|
406 | micromatch.js x 25,776 ops/sec ±0.68% (98 runs sampled)
|
407 | minimatch.js x 3,335 ops/sec ±1.09% (98 runs sampled)
|
408 |
|
409 | #2: basename.js
|
410 | micromatch.js x 24,676 ops/sec ±0.56% (95 runs sampled)
|
411 | minimatch.js x 4,908 ops/sec ±0.95% (97 runs sampled)
|
412 |
|
413 | #3: braces-no-glob.js
|
414 | micromatch.js x 473,492 ops/sec ±0.64% (96 runs sampled)
|
415 | minimatch.js x 27,705 ops/sec ±1.78% (91 runs sampled)
|
416 |
|
417 | #4: braces.js
|
418 | micromatch.js x 42,522 ops/sec ±0.63% (97 runs sampled)
|
419 | minimatch.js x 3,995 ops/sec ±1.36% (95 runs sampled)
|
420 |
|
421 | #5: immediate.js
|
422 | micromatch.js x 24,048 ops/sec ±0.72% (95 runs sampled)
|
423 | minimatch.js x 4,786 ops/sec ±1.40% (95 runs sampled)
|
424 |
|
425 | #6: large.js
|
426 | micromatch.js x 773 ops/sec ±0.62% (98 runs sampled)
|
427 | minimatch.js x 27.52 ops/sec ±0.66% (49 runs sampled)
|
428 |
|
429 | #7: long.js
|
430 | micromatch.js x 7,388 ops/sec ±0.64% (99 runs sampled)
|
431 | minimatch.js x 608 ops/sec ±0.95% (95 runs sampled)
|
432 |
|
433 | #8: mid.js
|
434 | micromatch.js x 41,193 ops/sec ±0.74% (99 runs sampled)
|
435 | minimatch.js x 2,724 ops/sec ±1.09% (97 runs sampled)
|
436 |
|
437 | #9: multi-patterns.js
|
438 | micromatch.js x 12,909 ops/sec ±0.71% (93 runs sampled)
|
439 | minimatch.js x 2,798 ops/sec ±1.45% (95 runs sampled)
|
440 |
|
441 | #10: no-glob.js
|
442 | micromatch.js x 430,787 ops/sec ±0.66% (98 runs sampled)
|
443 | minimatch.js x 47,222 ops/sec ±2.19% (86 runs sampled)
|
444 |
|
445 | #11: range.js
|
446 | micromatch.js x 474,561 ops/sec ±0.69% (97 runs sampled)
|
447 | minimatch.js x 10,819 ops/sec ±2.20% (88 runs sampled)
|
448 |
|
449 | #12: shallow.js
|
450 | micromatch.js x 239,098 ops/sec ±0.67% (96 runs sampled)
|
451 | minimatch.js x 27,782 ops/sec ±2.12% (92 runs sampled)
|
452 |
|
453 | #13: short.js
|
454 | micromatch.js x 707,905 ops/sec ±0.97% (97 runs sampled)
|
455 | minimatch.js x 52,171 ops/sec ±2.45% (84 runs sampled)
|
456 | ```
|
457 |
|
458 | ## Run tests
|
459 | Install dev dependencies.
|
460 |
|
461 | ```bash
|
462 | npm i -d && npm test
|
463 | ```
|
464 |
|
465 |
|
466 | ## Contributing
|
467 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/micromatch/issues)
|
468 |
|
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 06, 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
|