UNPKG

@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
'use strict'; 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