У меня есть эта строка:
"Test abc test test abc test test test abc test test abc"
Выполнение:
str = str.replace('abc', '');
кажется, только удалить первое вхождение abc
в строке выше.
Как я могу заменить все вхождения этого?
Примечание: не используйте это в коде, критичном к производительности.
В качестве альтернативы регулярным выражениям для простой литеральной строки, вы можете использовать
str = "Test abc test test abc test...".split("abc").join("");
Общая картина
str.split(search).join(replacement)
Раньше это было быстрее в некоторых случаях, чем при использовании replaceAll
регулярных выражений, но в современных браузерах этого больше не происходит.
Тест: https://jsperf.com/replace-all-vs-split-join
Вывод: если у вас есть сценарий использования, критичный к производительности (например, обработка сотен строк), используйте метод Regexp. Но для большинства типичных случаев лучше не беспокоиться о специальных символах.
String.prototype.replaceAll = function(f,r){return this.split(f).join(r);}
. Использование: "My string".replaceAll('st', '');
производит "Мое кольцо"replaceAll
функцию, и он станет таким же читабельным, как и все остальное. Поскольку производительность неплохая, нет причин избегать этого решения. Использование регулярного выражения с установленным g
флагом заменит все:
someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"
Смотрите здесь также
var sourceText
подсчитывать количество экземпляров ( numOfInstances
), используя substring
или разделять и подсчитывать длину (среди других стратегий), thatWhichYouWantToReplace
затем делать for (var i = 0; i < numOfInstances; i++){ sourceText = sourceText.replace('thatWhichYouWantToReplace', '');
}, или даже проще, просто использовать цикл while ( while sourceText.indexOf(thatWhichYouWantToReplace > -1){ sourceText = sourceText.replace(...)
), но я не понимаю, почему вы захотите сделать это таким образом, когда использование /g
так просто и, вероятно, более производительным. Сопоставить с глобальным регулярным выражением:
anotherString = someString.replace(/cat/g, 'dog');
str = str.replace(/abc/g, '');
В ответ на комментарий:
var find = 'abc';
var re = new RegExp(find, 'g');
str = str.replace(re, '');
В ответ на комментарий Click Upvote вы можете упростить его еще больше:
function replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
}
Примечание. Регулярные выражения содержат специальные (мета) символы, и поэтому опасно слепо передавать аргумент в find
функции выше без предварительной обработки для экранирования этих символов. Это описано в Mozilla Developer Network «s Guide JavaScript на регулярных выражениях , где они представляют следующую функцию полезности (которая изменилась , по крайней мере в два раза , так как этот ответ был изначально написано, так что не забудьте проверить сайт MDN для потенциальных обновлений):
function escapeRegExp(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
Таким образом, чтобы сделать replaceAll()
вышеописанную функцию более безопасной, ее можно изменить на следующую, если вы также включите escapeRegExp
:
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
replaceAll
реализации заключается в том, что она не будет работать, если find
содержит метасимволы. str = str.replace(/abc/g, '');
Или попробуйте функцию replaceAll отсюда:
Какие полезные методы JavaScript расширяют встроенные объекты?
str = str.replaceAll('abc', ''); OR
var search = 'abc';
str = str.replaceAll(search, '');
РЕДАКТИРОВАТЬ: разъяснения о заменеВсе наличие
Метод replaceAll добавлен в прототип String. Это означает, что он будет доступен для всех строковых объектов / литералов.
Например
var output = "test this".replaceAll('this', 'that'); //output is 'test that'.
output = output.replaceAll('that', 'this'); //output is 'test this'
Используйте регулярное выражение:
str.replace(/abc/g, '');
Моя реализация, очень понятно
function replaceAll(string, token, newtoken) {
if(token!=newtoken)
while(string.indexOf(token) > -1) {
string = string.replace(token, newtoken);
}
return string;
}
replaceAll("123434", "1234", "12")
должен вернуться, "1234"
но вместо этого возвращается "12"
. Обновить:
Уже несколько поздно для обновления, но так как я просто наткнулся на этот вопрос и заметил, что мой предыдущий ответ не тот, которым я доволен. Поскольку вопрос касался замены одного слова, невероятно, что никто не думал об использовании границ слов ( \b
).
'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"
Это простое регулярное выражение, которое в большинстве случаев избегает замены частей слов. Тем не менее, тире -
все еще считается границей слова. Поэтому в этом случае можно использовать условные выражения, чтобы избежать замены строк, таких как cool-cat
:
'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"
в основном, этот вопрос такой же, как и здесь: Javascript заменяет «» на «»
@ Майк, проверь ответ, который я там дал ... Регулярное выражение - не единственный способ заменить несколько вхождений подстроки, это далеко не так. Думай гибко, думай о разделении!
var newText = "the cat looks like a cat".split('cat').join('dog');
В качестве альтернативы, чтобы предотвратить замену частей слова - что будет делать и одобренный ответ! Вы можете обойти эту проблему, используя регулярные выражения, которые, я признаю, несколько более сложны и, как следствие, тоже немного медленнее:
var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
Вывод такой же, как принятый ответ, однако с использованием выражения / cat / g в этой строке:
var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ??
Ой, действительно, это, вероятно, не то, что вы хотите. Что же тогда? ИМХО, регулярное выражение, которое заменяет только 'условно'. (то есть не часть слова), вот так:
var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"
Я думаю, это отвечает вашим потребностям. Конечно, это не полная защита, но этого должно быть достаточно, чтобы вы начали. Я бы порекомендовал прочитать еще на этих страницах. Это окажется полезным в совершенствовании этого выражения для удовлетворения ваших конкретных потребностей.
http://www.javascriptkit.com/jsref/regexp.shtml
http://www.regular-expressions.info
Заключительное дополнение:
Учитывая, что этот вопрос по-прежнему получает много просмотров, я подумал, что мог бы добавить пример .replace
использования с функцией обратного вызова. В этом случае это значительно упрощает выражение и обеспечивает еще большую гибкость, например, замену на правильную заглавную букву или замену обоих cat
и сразу cats
:
'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
.replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
{
//check 1st, capitalize if required
var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
if (char1 === ' ' && char2 === 's')
{//replace plurals, too
cat = replacement + 's';
}
else
{//do not replace if dashes are matched
cat = char1 === '-' || char2 === '-' ? cat : replacement;
}
return char1 + cat + char2;//return replacement string
});
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar
Вот функция-прототип строки, основанная на принятом ответе:
String.prototype.replaceAll = function (find, replace) {
var str = this;
return str.replace(new RegExp(find, 'g'), replace);
};
РЕДАКТИРОВАТЬ
Если у вас find
будут специальные символы, вам нужно их избежать:
String.prototype.replaceAll = function (find, replace) {
var str = this;
return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};
Скрипка: http://jsfiddle.net/cdbzL/
find
содержит такие символы, как .
или $
которые имеют специальные значения в регулярных выражениях? var str = this
создает вторую ссылку на неизменяемую строку, к которой применяется replace
метод, который, в свою очередь, возвращает новую неизменяемую строку . Эти функции-прототипы возвращают новую неизменяемую строку, если нет, вы сможете написать someStrVar.replaceAll('o', '0');
и someStrVar
будут изменены. Вместо этого вы должны написать someStrVar = someStrVar.replaceAll('o', '0');
<- переназначить, чтобы установить переменную для хранения новой неизменной строки . нет способа обойти это. Попробуйте в консоли:x = 'foobar'; x.replaceAll('o', '0'); x;
Мне нравится этот метод (выглядит немного чище):
text = text.replace(new RegExp("cat","g"), "dog");
// зациклить, пока число вхождений не достигнет 0. ИЛИ просто скопировать / вставить
function replaceAll(find, replace, str)
{
while( str.indexOf(find) > -1)
{
str = str.replace(find, replace);
}
return str;
}
.indexOf
в переменной и используйте эту переменную в качестве второго параметра .indexOf
(минус длина ключевого слова плюс длина строки замены). Если то, что вы хотите найти, уже находится в строке, и у вас нет под рукой оператора regex escaper, вы можете использовать join / split:
function replaceMulti(haystack, needle, replacement)
{
return haystack.split(needle).join(replacement);
}
someString = 'the cat looks like a cat';
console.log(replaceMulti(someString, 'cat', 'dog'));
Для полноты картины я подумал о том, какой метод я должен использовать для этого. Есть два основных способа сделать это, как предлагают другие ответы на этой странице.
Примечание. Как правило, расширение встроенных прототипов в JavaScript обычно не рекомендуется. Я предоставляю в качестве расширений прототипа String просто в целях иллюстрации, демонстрируя различные реализации гипотетического стандартного метода на String
встроенном прототипе.
Реализация на основе регулярных выражений
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
Разделение и объединение (функциональная) реализация
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.split(search).join(replacement);
};
Не зная слишком много о том, как регулярные выражения работают за кулисами с точки зрения эффективности, я склонялся к расколу и присоединялся к реализации в прошлом, не задумываясь о производительности. Когда я задумался о том, что является более эффективным, и по какой причине я использовал это в качестве предлога, чтобы выяснить это.
На моем компьютере с Chrome Windows 8 реализация на основе регулярных выражений является самой быстрой , а реализация разбиения и объединения выполняется на 53% медленнее . Это означает, что регулярные выражения в два раза быстрее для ввода lorem ipsum, который я использовал.
Проверьте этот тест, запустив эти две реализации друг против друга.
Как отмечается в комментарии ниже @ThomasLeduc и других, может быть проблема с реализацией на основе регулярных выражений, если она search
содержит определенные символы, которые зарезервированы как специальные символы в регулярных выражениях . Реализация предполагает, что вызывающая сторона будет избегать строки заранее или будет передавать только те строки, которые не имеют символов в таблице в регулярных выражениях (MDN).
MDN также предоставляет реализацию, позволяющую избежать наших строк. Было бы хорошо, если бы это было также стандартизировано RegExp.escape(str)
, но, увы, его не существует:
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}
Мы могли бы вызвать escapeRegExp
в нашей String.prototype.replaceAll
реализации, однако, я не уверен, насколько это повлияет на производительность (потенциально даже для строк, для которых экранирование не требуется, как для всех буквенно-цифровых строк).
var str = "ff ff f f a de def";
str = str.replace(/f/g,'');
alert(str);
Для замены всех видов символов попробуйте этот код:
Suppose we have need to send " and \ in my string, then we will convert it " to \" and \ to \\
Таким образом, этот метод решит эту проблему.
String.prototype.replaceAll = function (find, replace) {
var str = this;
return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};
var message = $('#message').val();
message = message.replaceAll('\\', '\\\\'); /*it will replace \ to \\ */
message = message.replaceAll('"', '\\"'); /*it will replace " to \\"*/
Я использовал Ajax, и мне нужно было отправить параметры в формате JSON. Тогда мой метод выглядит так:
function sendMessage(source, messageID, toProfileID, userProfileID) {
if (validateTextBox()) {
var message = $('#message').val();
message = message.replaceAll('\\', '\\\\');
message = message.replaceAll('"', '\\"');
$.ajax({
type: "POST",
async: "false",
contentType: "application/json; charset=utf-8",
url: "services/WebService1.asmx/SendMessage",
data: '{"source":"' + source + '","messageID":"' + messageID + '","toProfileID":"' + toProfileID + '","userProfileID":"' + userProfileID + '","message":"' + message + '"}',
dataType: "json",
success: function (data) {
loadMessageAfterSend(toProfileID, userProfileID);
$("#<%=PanelMessageDelete.ClientID%>").hide();
$("#message").val("");
$("#delMessageContainer").show();
$("#msgPanel").show();
},
error: function (result) {
alert("message sending failed");
}
});
}
else {
alert("Please type message in message box.");
$("#message").focus();
}
}
String.prototype.replaceAll = function (find, replace) {
var str = this;
return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};
Попробуй это:
String.prototype.replaceAll = function (sfind, sreplace) {
var str = this;
while (str.indexOf(sfind) > -1) {
str = str.replace(sfind, sreplace);
}
return str;
};
Это самая быстрая версия, которая не использует регулярные выражения .
replaceAll = function(string, omit, place, prevstring) {
if (prevstring && string === prevstring)
return string;
prevstring = string.replace(omit, place);
return replaceAll(prevstring, omit, place, string)
}
Это почти в два раза быстрее, чем метод split и join.
Как указано в комментарии здесь, это не будет работать, если ваша omit
переменная содержит place
, как в:, replaceAll("string", "s", "ss")
потому что она всегда сможет заменить другое вхождение слова.
На моей рекурсивной замене есть еще один jsperf с вариантами, которые идут еще быстрее ( http://jsperf.com/replace-all-vs-split-join/12 )!
- Обновление от 27 июля 2017 года. Похоже, что RegExp теперь имеет самую быструю производительность в недавно выпущенном Chrome 59.
if(place.replace(omit) === omit) {
No match, поэтому можно безопасно использовать замену цикла } else {
Match, поэтому используйте другой метод, например split и join}
while (str.indexOf('abc') !== -1)
{
str = str.replace('abc', '');
}
Если вы можете использовать библиотеку, тогда вы получите преимущества тестирования и поддержки сообщества, которые связаны с библиотечной функцией. Например, библиотека string.js имеет функцию replaceAll (), которая делает то, что вы ищете:
// Include a reference to the string.js library and call it (for example) S.
str = S(str).replaceAll('abc', '').s;
Если вы пытаетесь гарантировать, что искомая строка не будет существовать даже после замены, вам нужно использовать цикл.
Например:
var str = 'test aabcbc';
str = str.replace(/abc/g, '');
После завершения у вас все еще будет «test abc»!
Самый простой цикл для решения этой проблемы:
var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
str.replace(/abc/g, '');
}
Но это запускает замену дважды для каждого цикла. Возможно (рискуя быть отвергнутым), что может быть объединено для немного более эффективной, но менее читаемой формы:
var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!
Это может быть особенно полезно при поиске дубликатов строк.
Например, если у нас есть «a ,,, b» и мы хотим удалить все повторяющиеся запятые.
[В этом случае можно сделать .replace (/, + / g, ','), но в какой-то момент регулярное выражение становится сложным и достаточно медленным, чтобы выполнять цикл.]
function replaceAll(str, find, replace) {
var i = str.indexOf(find);
if (i > -1){
str = str.replace(find, replace);
i = i + replace.length;
var st2 = str.substring(i);
if(st2.indexOf(find) > -1){
str = str.substring(0,i) + replaceAll(st2, find, replace);
}
}
return str;
}
Просто добавь /g
document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi');
в
// Replace 'hello' string with /hello/g regular expression.
document.body.innerHTML = document.body.innerHTML.replace(/hello/g, 'hi');
/g
означает глобальный
Замена одинарных кавычек:
function JavaScriptEncode(text){
text = text.replace(/'/g,''')
// More encode here if required
return text;
}
Я использую p для сохранения результата предыдущей замены рекурсии:
function replaceAll(s, m, r, p) {
return s === p || r.contains(m) ? s : replaceAll(s.replace(m, r), m, r, s);
}
Он заменит все вхождения в строке s, пока это не станет возможным:
replaceAll('abbbbb', 'ab', 'a') → 'abbbb' → 'abbb' → 'abb' → 'ab' → 'a'
Чтобы избежать бесконечного цикла, я проверяю, содержит ли замена r совпадение m :
replaceAll('abbbbb', 'a', 'ab') → 'abbbbb'
Вы можете просто использовать метод ниже
/**
* Replace all the occerencess of $find by $replace in $originalString
* @param {originalString} input - Raw string.
* @param {find} input - Target key word or regex that need to be replaced.
* @param {replace} input - Replacement key word
* @return {String} Output string
*/
function replaceAll(originalString, find, replace) {
return originalString.replace(new RegExp(find, 'g'), replace);
};
У меня работает следующая функция:
String.prototype.replaceAllOccurence = function(str1, str2, ignore)
{
return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2);
} ;
Теперь вызовите функции так:
"you could be a Project Manager someday, if you work like this.".replaceAllOccurence ("you", "I");
Просто скопируйте и вставьте этот код в консоли браузера в TEST.
Вот рабочий код с прототипом:
String.prototype.replaceAll = function(find, replace) {
var str = this;
return str.replace(new RegExp(find.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"), 'g'), replace);
};
function replaceAll(str, find, replace) {
var $r="";
while($r!=str){
$r = str;
str = str.replace(find, replace);
}
return str;
}
Хотя люди упоминали об использовании регулярных выражений, но есть лучший подход, если вы хотите заменить текст независимо от случая текста. Как прописные или строчные. Используйте ниже синтаксис
//Consider below example
originalString.replace(/stringToBeReplaced/gi, '');
//Output will be all the occurrences removed irrespective of casing.
Вы можете сослаться на подробный пример здесь .
Скажем, вы хотите заменить все «abc» на «x»:
let some_str = 'abc def def lom abc abc def'.split('abc').join('x')
console.log(some_str) //x def def lom x x def
Я пытался придумать что-то более простое, чем модификация прототипа строки.
aba
вababa
сca
, что приводит вы ожидаете?caba
?abca
?cca
?