You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
3.2 KiB
JavaScript

/*!
* expand-brackets <https://github.com/jonschlinkert/expand-brackets>
*
* Copyright (c) 2015 Jon Schlinkert.
* Licensed under the MIT license.
*/
'use strict';
var isPosixBracket = require('is-posix-bracket');
/**
* POSIX character classes
*/
var POSIX = {
alnum: 'a-zA-Z0-9',
alpha: 'a-zA-Z',
blank: ' \\t',
cntrl: '\\x00-\\x1F\\x7F',
digit: '0-9',
graph: '\\x21-\\x7E',
lower: 'a-z',
print: '\\x20-\\x7E',
punct: '-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
space: ' \\t\\r\\n\\v\\f',
upper: 'A-Z',
word: 'A-Za-z0-9_',
xdigit: 'A-Fa-f0-9',
};
/**
* Expose `brackets`
*/
module.exports = brackets;
function brackets(str) {
if (!isPosixBracket(str)) {
return str;
}
var negated = false;
if (str.indexOf('[^') !== -1) {
negated = true;
str = str.split('[^').join('[');
}
if (str.indexOf('[!') !== -1) {
negated = true;
str = str.split('[!').join('[');
}
var a = str.split('[');
var b = str.split(']');
var imbalanced = a.length !== b.length;
var parts = str.split(/(?::\]\[:|\[?\[:|:\]\]?)/);
var len = parts.length, i = 0;
var end = '', beg = '';
var res = [];
// start at the end (innermost) first
while (len--) {
var inner = parts[i++];
if (inner === '^[!' || inner === '[!') {
inner = '';
negated = true;
}
var prefix = negated ? '^' : '';
var ch = POSIX[inner];
if (ch) {
res.push('[' + prefix + ch + ']');
} else if (inner) {
if (/^\[?\w-\w\]?$/.test(inner)) {
if (i === parts.length) {
res.push('[' + prefix + inner);
} else if (i === 1) {
res.push(prefix + inner + ']');
} else {
res.push(prefix + inner);
}
} else {
if (i === 1) {
beg += inner;
} else if (i === parts.length) {
end += inner;
} else {
res.push('[' + prefix + inner + ']');
}
}
}
}
var result = res.join('|');
var rlen = res.length || 1;
if (rlen > 1) {
result = '(?:' + result + ')';
rlen = 1;
}
if (beg) {
rlen++;
if (beg.charAt(0) === '[') {
if (imbalanced) {
beg = '\\[' + beg.slice(1);
} else {
beg += ']';
}
}
result = beg + result;
}
if (end) {
rlen++;
if (end.slice(-1) === ']') {
if (imbalanced) {
end = end.slice(0, end.length - 1) + '\\]';
} else {
end = '[' + end;
}
}
result += end;
}
if (rlen > 1) {
result = result.split('][').join(']|[');
if (result.indexOf('|') !== -1 && !/\(\?/.test(result)) {
result = '(?:' + result + ')';
}
}
result = result.replace(/\[+=|=\]+/g, '\\b');
return result;
}
brackets.makeRe = function(pattern) {
try {
return new RegExp(brackets(pattern));
} catch (err) {}
};
brackets.isMatch = function(str, pattern) {
try {
return brackets.makeRe(pattern).test(str);
} catch (err) {
return false;
}
};
brackets.match = function(arr, pattern) {
var len = arr.length, i = 0;
var res = arr.slice();
var re = brackets.makeRe(pattern);
while (i < len) {
var ele = arr[i++];
if (!re.test(ele)) {
continue;
}
res.splice(i, 1);
}
return res;
};