voca
Version:
The ultimate JavaScript string library
83 lines (64 loc) • 2.37 kB
JavaScript
;
require('./internal/is_nil.js');
require('./is_string.js');
var coerce_to_string = require('./internal/coerce_to_string.js');
/**
* Replaces all occurrences of `search` with `replace`. <br/>
*
* @function replaceAll
* @static
* @since 1.0.0
* @memberOf Manipulate
* @param {string} [subject=''] The string to verify.
* @param {string|RegExp} search The search pattern to replace. If `search` is a string, a simple string match is evaluated.
* All matches are replaced.
* @param {string|Function} replace The string or function which invocation result replaces all `search` matches.
* @return {string} Returns the replacement result.
* @example
* v.replaceAll('good morning', 'o', '*');
* // => 'g**d m*rning'
* v.replaceAll('evening', /n/g, 's');
* // => 'evesisg'
*
*/
function replaceAll(subject, search, replace) {
var subjectString = coerce_to_string.coerceToString(subject);
if (search instanceof RegExp) {
if (search.flags.indexOf('g') === -1) {
throw new TypeError('search argument is a non-global regular expression');
}
return subjectString.replace(search, replace);
}
var searchString = coerce_to_string.coerceToString(search);
var isFunctionalReplace = typeof replace === 'function';
if (!isFunctionalReplace) {
replace = coerce_to_string.coerceToString(replace);
}
var searchLength = searchString.length;
if (searchLength === 0) {
return replaceAll(subject, /(?:)/g, replace);
}
var advanceBy = searchLength > 1 ? searchLength : 1;
var matchPositions = [];
var position = subjectString.indexOf(searchString, 0);
while (position !== -1) {
matchPositions.push(position);
position = subjectString.indexOf(searchString, position + advanceBy);
}
var endOfLastMatch = 0;
var result = '';
for (var i = 0; i < matchPositions.length; i++) {
var _position = matchPositions[i];
var replacement = replace;
if (isFunctionalReplace) {
replacement = coerce_to_string.coerceToString(replace.call(undefined, searchString, _position, subjectString));
}
result += subjectString.slice(endOfLastMatch, _position) + replacement;
endOfLastMatch = _position + searchLength;
}
if (endOfLastMatch < subjectString.length) {
result += subjectString.slice(endOfLastMatch);
}
return result;
}
module.exports = replaceAll;