Skip to content

Commit

Permalink
Add micromatch.capture to return captured matches
Browse files Browse the repository at this point in the history
  • Loading branch information
devongovett committed Sep 4, 2017
1 parent 12e9d37 commit e184907
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 2 deletions.
38 changes: 38 additions & 0 deletions index.js
Expand Up @@ -516,6 +516,44 @@ micromatch.matcher = function matcher(pattern, options) {
return fn;
};

/**
* Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match.
*
* ```js
* var mm = require('micromatch');
* mm.capture(pattern, string[, options]);
*
* console.log(mm.capture('test/*.js', 'test/foo.js));
* //=> ['foo']
* console.log(mm.capture('test/*.js', 'foo/bar.css'));
* //=> null
* ```
* @param {String} `pattern` Glob pattern to use for matching.
* @param {String} `string` String to match
* @param {Object} `options` See available [options](#options) for changing how matches are performed
* @return {Boolean} Returns an array of captures if the string matches the glob pattern, otherwise `null`.
* @api public
*/

micromatch.capture = function(pattern, str, options) {
var re = micromatch.makeRe(pattern, extend({capture: true}, options));
var unixify = utils.unixify(options);

function match() {
return function(string) {
var match = re.exec(unixify(string));
if (!match) {
return null;
}

return match.slice(1);
};
}

var capture = memoize('capture', pattern, options, match);
return capture(str);
};

/**
* Create a regular expression from the given glob `pattern`.
*
Expand Down
4 changes: 2 additions & 2 deletions test/brackets.js
Expand Up @@ -22,8 +22,8 @@ describe('brackets', function() {
assert.equal(create('[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]'), '[a-zA-Z0-9a-zA-Z \\t\\x00-\\x1F\\x7F0-9\\x21-\\x7Ea-z\\x20-\\x7E \\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~ \\t\\r\\n\\v\\fA-ZA-Fa-f0-9]');
assert.equal(create('[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:lower:][:space:][:upper:][:xdigit:]]'), '[^a-zA-Z0-9a-zA-Z \\t\\x00-\\x1F\\x7F0-9a-z \\t\\r\\n\\v\\fA-ZA-Fa-f0-9]');
assert.equal(create('[a-c[:digit:]x-z]'), '[a-c0-9x-z]');
assert.equal(create('[_[:alpha:]][_[:alnum:]][_[:alnum:]]*', {bash: false}), '[_a-zA-Z][_a-zA-Z0-9][_a-zA-Z0-9]*?(\\/|$)', []);
assert.equal(create('[_[:alpha:]][_[:alnum:]][_[:alnum:]]*'), '[_a-zA-Z][_a-zA-Z0-9][_a-zA-Z0-9][^/]*?(\\/|$)', []);
assert.equal(create('[_[:alpha:]][_[:alnum:]][_[:alnum:]]*', {bash: false}), '[_a-zA-Z][_a-zA-Z0-9][_a-zA-Z0-9]*?(?:\\/|$)', []);
assert.equal(create('[_[:alpha:]][_[:alnum:]][_[:alnum:]]*'), '[_a-zA-Z][_a-zA-Z0-9][_a-zA-Z0-9][^/]*?(?:\\/|$)', []);
});
});

Expand Down
67 changes: 67 additions & 0 deletions test/capture.js
@@ -0,0 +1,67 @@
var capture = require('../').capture;
var assert = require('assert');

describe('.capture()', function() {
it('should return null if no match', function() {
assert.equal(capture('test/*', 'hi/123'), null);
});

it('should return an empty array if there are no captures', function() {
assert.deepEqual(capture('test/hi', 'test/hi'), []);
});

it('should capture stars', function() {
assert.deepEqual(capture('test/*', 'test/foo'), ['foo']);
assert.deepEqual(capture('test/*/bar', 'test/foo/bar'), ['foo']);
assert.deepEqual(capture('test/*/bar/*', 'test/foo/bar/baz'), ['foo', 'baz']);
assert.deepEqual(capture('test/*.js', 'test/foo.js'), ['foo']);
assert.deepEqual(capture('test/*-controller.js', 'test/foo-controller.js'), ['foo']);
});

it('should capture globstars', function() {
assert.deepEqual(capture('test/**/*.js', 'test/a.js'), ['', 'a']);
assert.deepEqual(capture('test/**/*.js', 'test/dir/a.js'), ['dir', 'a']);
assert.deepEqual(capture('test/**/*.js', 'test/dir/test/a.js'), ['dir/test', 'a']);
});

it('should capture extglobs', function() {
assert.deepEqual(capture('test/+(a|b)/*.js', 'test/a/x.js'), ['a', 'x']);
assert.deepEqual(capture('test/+(a|b)/*.js', 'test/b/x.js'), ['b', 'x']);
assert.deepEqual(capture('test/+(a|b)/*.js', 'test/ab/x.js'), ['ab', 'x']);
});

it('should capture paren groups', function() {
assert.deepEqual(capture('test/(a|b)/x.js', 'test/a/x.js'), ['a']);
assert.deepEqual(capture('test/(a|b)/x.js', 'test/b/x.js'), ['b']);
});

it('should capture star groups', function() {
assert.deepEqual(capture('test/a*(a|b)/x.js', 'test/a/x.js'), ['']);
assert.deepEqual(capture('test/a*(a|b)/x.js', 'test/aa/x.js'), ['a']);
assert.deepEqual(capture('test/a*(a|b)/x.js', 'test/ab/x.js'), ['b']);
assert.deepEqual(capture('test/a*(a|b)/x.js', 'test/aba/x.js'), ['ba']);
});

it('should capture plus groups', function() {
assert.deepEqual(capture('test/+(a|b)/x.js', 'test/a/x.js'), ['a']);
assert.deepEqual(capture('test/+(a|b)/x.js', 'test/b/x.js'), ['b']);
assert.deepEqual(capture('test/+(a|b)/x.js', 'test/ab/x.js'), ['ab']);
assert.deepEqual(capture('test/+(a|b)/x.js', 'test/aba/x.js'), ['aba']);
});

it('should capture optional groups', function() {
assert.deepEqual(capture('test/a?(a|b)/x.js', 'test/a/x.js'), ['']);
assert.deepEqual(capture('test/a?(a|b)/x.js', 'test/ab/x.js'), ['b']);
assert.deepEqual(capture('test/a?(a|b)/x.js', 'test/aa/x.js'), ['a']);
});

it('should capture @ groups', function() {
assert.deepEqual(capture('test/@(a|b)/x.js', 'test/a/x.js'), ['a']);
assert.deepEqual(capture('test/@(a|b)/x.js', 'test/b/x.js'), ['b']);
});

it('should capture negated groups', function() {
assert.deepEqual(capture('test/!(a|b)/x.js', 'test/x/x.js'), ['x']);
assert.deepEqual(capture('test/!(a|b)/x.js', 'test/y/x.js'), ['y']);
});
});

0 comments on commit e184907

Please sign in to comment.