123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- /*!
- * extglob <https://github.com/jonschlinkert/extglob>
- *
- * Copyright (c) 2015, Jon Schlinkert.
- * Licensed under the MIT License.
- */
- 'use strict';
- /**
- * Module dependencies
- */
- var isExtglob = require('is-extglob');
- var re, cache = {};
- /**
- * Expose `extglob`
- */
- module.exports = extglob;
- /**
- * Convert the given extglob `string` to a regex-compatible
- * string.
- *
- * ```js
- * var extglob = require('extglob');
- * extglob('!(a?(b))');
- * //=> '(?!a(?:b)?)[^/]*?'
- * ```
- *
- * @param {String} `str` The string to convert.
- * @param {Object} `options`
- * @option {Boolean} [options] `esc` If `false` special characters will not be escaped. Defaults to `true`.
- * @option {Boolean} [options] `regex` If `true` a regular expression is returned instead of a string.
- * @return {String}
- * @api public
- */
- function extglob(str, opts) {
- opts = opts || {};
- var o = {}, i = 0;
- // fix common character reversals
- // '*!(.js)' => '*.!(js)'
- str = str.replace(/!\(([^\w*()])/g, '$1!(');
- // support file extension negation
- str = str.replace(/([*\/])\.!\([*]\)/g, function (m, ch) {
- if (ch === '/') {
- return escape('\\/[^.]+');
- }
- return escape('[^.]+');
- });
- // create a unique key for caching by
- // combining the string and options
- var key = str
- + String(!!opts.regex)
- + String(!!opts.contains)
- + String(!!opts.escape);
- if (cache.hasOwnProperty(key)) {
- return cache[key];
- }
- if (!(re instanceof RegExp)) {
- re = regex();
- }
- opts.negate = false;
- var m;
- while (m = re.exec(str)) {
- var prefix = m[1];
- var inner = m[3];
- if (prefix === '!') {
- opts.negate = true;
- }
- var id = '__EXTGLOB_' + (i++) + '__';
- // use the prefix of the _last_ (outtermost) pattern
- o[id] = wrap(inner, prefix, opts.escape);
- str = str.split(m[0]).join(id);
- }
- var keys = Object.keys(o);
- var len = keys.length;
- // we have to loop again to allow us to convert
- // patterns in reverse order (starting with the
- // innermost/last pattern first)
- while (len--) {
- var prop = keys[len];
- str = str.split(prop).join(o[prop]);
- }
- var result = opts.regex
- ? toRegex(str, opts.contains, opts.negate)
- : str;
- result = result.split('.').join('\\.');
- // cache the result and return it
- return (cache[key] = result);
- }
- /**
- * Convert `string` to a regex string.
- *
- * @param {String} `str`
- * @param {String} `prefix` Character that determines how to wrap the string.
- * @param {Boolean} `esc` If `false` special characters will not be escaped. Defaults to `true`.
- * @return {String}
- */
- function wrap(inner, prefix, esc) {
- if (esc) inner = escape(inner);
- switch (prefix) {
- case '!':
- return '(?!' + inner + ')[^/]' + (esc ? '%%%~' : '*?');
- case '@':
- return '(?:' + inner + ')';
- case '+':
- return '(?:' + inner + ')+';
- case '*':
- return '(?:' + inner + ')' + (esc ? '%%' : '*')
- case '?':
- return '(?:' + inner + '|)';
- default:
- return inner;
- }
- }
- function escape(str) {
- str = str.split('*').join('[^/]%%%~');
- str = str.split('.').join('\\.');
- return str;
- }
- /**
- * extglob regex.
- */
- function regex() {
- return /(\\?[@?!+*$]\\?)(\(([^()]*?)\))/;
- }
- /**
- * Negation regex
- */
- function negate(str) {
- return '(?!^' + str + ').*$';
- }
- /**
- * Create the regex to do the matching. If
- * the leading character in the `pattern` is `!`
- * a negation regex is returned.
- *
- * @param {String} `pattern`
- * @param {Boolean} `contains` Allow loose matching.
- * @param {Boolean} `isNegated` True if the pattern is a negation pattern.
- */
- function toRegex(pattern, contains, isNegated) {
- var prefix = contains ? '^' : '';
- var after = contains ? '$' : '';
- pattern = ('(?:' + pattern + ')' + after);
- if (isNegated) {
- pattern = prefix + negate(pattern);
- }
- return new RegExp(prefix + pattern);
- }
|