Распространенная ошибка
Почти во всех ответах на этой странице используется кумулятивная замена и, таким образом, имеется тот же недостаток, когда заменяемые строки сами подлежат замене.Вот пара примеров, где этот шаблон не работает (h / t @KurokiKaze @derekdreery):
function replaceCumulative(str, find, replace) {
for (var i = 0; i < find.length; i++)
str = str.replace(new RegExp(find[i],"g"), replace[i]);
return str;
};
// Fails in some cases:
console.log( replaceCumulative( "tar pit", ['tar','pit'], ['capitol','house'] ) );
console.log( replaceCumulative( "you & me", ['you','me'], ['me','you'] ) );
Решение
function replaceBulk( str, findArray, replaceArray ){
var i, regex = [], map = {};
for( i=0; i<findArray.length; i++ ){
regex.push( findArray[i].replace(/([-[\]{}()*+?.\\^$|#,])/g,'\\$1') );
map[findArray[i]] = replaceArray[i];
}
regex = regex.join('|');
str = str.replace( new RegExp( regex, 'g' ), function(matched){
return map[matched];
});
return str;
}
// Test:
console.log( replaceBulk( "tar pit", ['tar','pit'], ['capitol','house'] ) );
console.log( replaceBulk( "you & me", ['you','me'], ['me','you'] ) );
Примечание:
Это более совместимый вариант решения @ elchininet's , в котором используется map()
и Array.indexOf()
и, следовательно, не будут работать в IE8 и старше.
Реализация @ elchininet вернее PHP str_replace()
, поскольку она также позволяет использовать строки в качестве параметров поиска / замены и будет использовать первое совпадение с массивом поиска, если есть дубликаты (моя версия будет использовать последний).Я не принял строки в этой реализации, потому что этот случай уже обработан встроенным в JS String.replace()
.