@forensic-js/regex
Version:
A module that builds on the existing RegExp module, making it easier working with text matching and replacement both in the browser and node environments
218 lines (174 loc) • 6.81 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
var utils = require('@forensic-js/utils');
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
}
}
function _iterableToArray(iter) {
if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance");
}
var replacementText = '';
var callback = function callback(matches, counts) {
return replacementText;
};
/**
* resolve regex pattern, normalizing the modifiers
*/
var resolveRegexPattern = function resolveRegexPattern(pattern) {
var modifiers = pattern.ignoreCase ? 'gmi' : 'gm';
return new RegExp(pattern.source, modifiers);
};
/**
* resolves replaceCount to a number
*/
var resolveReplaceCount = function resolveReplaceCount(replaceCount) {
if (typeof replaceCount === 'boolean') {
return replaceCount ? 1 : -1;
} else {
return replaceCount;
}
};
/**
* ensure that number of replacement texts at least equals number of patterns
*/
var resolveReplacements = function resolveReplacements(patterns, replacements) {
var patternsCount = patterns.length,
replacementsCount = replacements.length,
difference = patternsCount - replacementsCount;
if (difference > 0) {
var fillWith = replacements[replacementsCount - 1];
return [].concat(_toConsumableArray(replacements), _toConsumableArray(Array(difference).fill(fillWith)));
} else {
return replacements;
}
};
/**
* resolve all capturing groups
*/
var resolveCapturingGroups = function resolveCapturingGroups(callback, matches, count) {
var text = callback(matches, count);
var pattern = resolveRegexPattern(/[$]:(\d+)/);
var result = '';
var length = matches.length;
var startIndex = 0;
var start = -1;
while (++start < length) {
var match = pattern.exec(text);
if (!match) {
break;
}
var index = match.index;
var len = match[0].length;
var current = Number.parseInt(match[1], 10);
var _replacementText = current < length ? matches[current] : match[0];
result += text.slice(startIndex, index) + _replacementText;
startIndex = index + len;
}
result += text.slice(startIndex);
return result;
};
/**
* run replacements using regex pattern as search criteria
*/
var runRegex = function runRegex(pattern, callback, text, replaceCount) {
var result = '',
start = 0,
counts = 0;
while (++counts && (replaceCount === -1 || counts <= replaceCount)) {
var _matches = pattern.exec(text);
if (!_matches) {
break;
}
var index = _matches.index,
len = _matches[0].length;
result += text.slice(start, index) + resolveCapturingGroups(callback, _matches, counts);
start = index + len;
}
result += text.slice(start);
return result;
};
/**
* run replacements using string pattern as search criteria
*/
var runString = function runString(pattern, callback, text, caseSensitive, replaceCount) {
var result = '',
start = 0,
counts = 0;
var searchFor = caseSensitive ? pattern : pattern.toLowerCase(),
searchFrom = caseSensitive ? text : text.toLowerCase(),
len = pattern.length;
while (++counts && (replaceCount === -1 || counts <= replaceCount)) {
var index = searchFrom.indexOf(searchFor, start);
if (index <= -1) {
break;
}
result += text.slice(start, index) + resolveCapturingGroups(callback, [pattern], counts);
start = index + len;
}
result += text.slice(start);
return result;
};
var cordinateReplacement = function cordinateReplacement(pattern, callback, text, caseSensitive, replaceCount) {
var result = '';
if (utils.isRegex(pattern)) {
result = runRegex(resolveRegexPattern(pattern), callback, text, replaceCount);
} else {
result = runString(pattern, callback, text, caseSensitive, replaceCount);
}
return result;
};
/**
* iteratively replace every occurence of search patterns with the given replacements text in the
* given text
* @param patterns - search patterns, can be string or regex expressions,
* @param replacements - replacement text for each search pattern
* @param text - the text string to work on
* @param caseSensitive - specifies if search is case sensitive, this only applies to string
* patterns. for regex patterns, use RegExp ignoreCase flag (i)
* @param replaceCount - number of times to replace occurrences for each search pattern. by default
* all occurrences will be replaced. specify true or 1 to replace only first occurrence.
*/
var replace = function replace(patterns, replacements, text) {
var caseSensitive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var replaceCount = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
text = text.toString();
patterns = utils.makeArray(patterns);
replacements = resolveReplacements(patterns, utils.makeArray(replacements));
var count = resolveReplaceCount(replaceCount);
return patterns.reduce(function (result, pattern, index) {
replacementText = replacements[index];
return cordinateReplacement(pattern, callback, result, caseSensitive, count);
}, text);
};
/**
* iteratively replace every occurence of search patterns with the return value of the
* given callback function in the given text
* @param patterns - search patterns, can be string or regex expressions,
* @param callback - the callback function
* @param text - the text string to work on
* @param caseSensitive - specifies if search is case sensitive, this only applies to string
* patterns. for regex patterns, use RegExp ignoreCase flag (i)
* @param replaceCount - number of times to replace occurrences for each search pattern. by default
* all occurrences will be replaced. specify true or 1 to replace only first occurrence.
*/
var replaceCallback = function replaceCallback(patterns, callback, text) {
var caseSensitive = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var replaceCount = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
text = text.toString();
var count = resolveReplaceCount(replaceCount);
return utils.makeArray(patterns).reduce(function (result, pattern) {
return cordinateReplacement(pattern, callback, result, caseSensitive, count);
}, text);
};
exports.replace = replace;
exports.replaceCallback = replaceCallback;
//# sourceMappingURL=index.js.map
;