You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
3.2 KiB
163 lines
3.2 KiB
/*! |
|
* 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; |
|
};
|
|
|