/*! * 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; };