30 ответов:
для полноты картины, я начал думать о том, какой метод я должен использовать для этого. Есть в основном два способа сделать это, как предложено другими ответами на этой странице.
Примечание: в целом, расширение встроенных прототипов в JavaScript, как правило, не рекомендуется. Я предоставляю в качестве расширений на прототипе строки просто для иллюстрации, показывая различные реализации гипотетического стандартного метода на
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, который я использовал.
зацените benchmark запуск этих двух реализаций друг против друга.
как отмечено в комментарии ниже @ThomasLeduc и другие, может быть проблема с реализацией на основе регулярных выражений, если
searchсодержит определенные символы, которые зарезервированы в качестве специальные символы в регулярных выражениях. Реализация предполагает, что вызывающий объект будет экранировать строку заранее или будет передавать только строки, которые не содержат символов в таблице в Регулярные Выражения (MDN).MDN также предоставляет реализацию для выхода из наших строк. Было бы неплохо, если бы это было также стандартизировано как
RegExp.escape(str), но, увы, его не существует:function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\]/g, "\$&"); // $& means the whole matched string }мы могли бы назвать
escapeRegExpв нашейString.prototype.replaceAllреализация, однако, я не уверен, насколько это повлияет на производительность (потенциально даже для строк, для которых escape не требуется, как и все буквенно-цифровые строки).
str = str.replace(/abc/g, '');в ответ на комментарий:
var find = 'abc'; var re = new RegExp(find, 'g'); str = str.replace(re, '');в ответ Нажмите Upvoteкомментарий, вы могли бы упростить его еще больше:
function replaceAll(str, find, replace) { return str.replace(new RegExp(find, 'g'), replace); }Примечание: регулярные выражения содержат специальные (мета) символы, и поэтому опасно слепо передавать аргумент в
findфункции выше, без предварительной обработки его, чтобы избежать этих знаков. Это описано в Mozilla Developer Network ' s JavaScript Руководство по регулярным выражениям, где они представляют следующую функцию полезности:function escapeRegExp(str) { return str.replace(/([.*+?^=!:${}()|\[\]\/\])/g, "\"); }Итак, чтобы сделать
replaceAll()функция выше безопаснее, она может быть изменена на следующее, Если вы также включитеescapeRegExp:function replaceAll(str, find, replace) { return str.replace(new RegExp(escapeRegExp(find), 'g'), replace); }
Примечание: не используйте это в реальном коде.
в качестве альтернативы регулярным выражениям для простой литеральной строки можно использовать
str = "Test abc test test abc test...".split("abc").join("");общая картина
str.split(search).join(replacement)Это раньше было быстрее в некоторых случаях, чем с помощью
replaceAllи регулярное выражение, но это, кажется, не быть больше в современных браузерах. Таким образом, это действительно должно использоваться только как быстрый хак, чтобы избежать необходимости избегать регулярного выражения, а не в реальный код.
используя регулярное выражение с
gфлаг set заменит все:someString = 'the cat looks like a cat'; anotherString = someString.replace(/cat/g, 'dog'); // anotherString now contains "the dog looks like a dog"посмотреть здесь
вот функция прототипа строки, основанная на принятом ответе:
String.prototype.replaceAll = function (find, replace) { var str = this; return str.replace(new RegExp(find, 'g'), replace); };EDIT
Если
findбудет содержать специальные символы, то вам нужно убежать от них:String.prototype.replaceAll = function (find, replace) { var str = this; return str.replace(new RegExp(find.replace(/[-\/\^$*+?.()|[\]{}]/g, '\$&'), 'g'), replace); };Скрипка:http://jsfiddle.net/cdbzL/
обновление:
это несколько поздно для обновления, но так как я просто наткнулся на этот вопрос, и заметил, что мой предыдущий ответ не один я доволен. Поскольку вопрос заключался в замене одного слова, невероятно, что никто не думал использовать границы слов (
\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,'dog'); //"a dog is not a cool-cat"
в принципе, этот вопрос такой же как вопрос здесь: Javascript заменить "'"на"""
@Майк, проверьте ответ, который я дал там... регулярное выражение - это не единственный способ заменить несколько вхождений subsrting, далеко не так. Думаю, покладистый, думаю, раскол!
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,"dog");вывод такой же, как и принятый ответ, однако, используя выражение /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" ??Ой действительно, это, вероятно, не то, что вы хотите. А что же тогда? ИМХО, регулярное выражение, которое только заменяет' cat ' условно. (т. е. не часть слова), как Итак:
var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"dog"); //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
сопоставление с глобальным регулярным выражением:
anotherString = someString.replace(/cat/g, 'dog');
str = str.replace(/abc/g, '');или попробуйте функцию replaceAll отсюда:
каковы полезные методы JavaScript, которые расширяют встроенные объекты?
str = str.replaceAll('abc', ''); OR var search = 'abc'; str = str.replaceAll(search, '');EDIT: уточнение о доступности replaceAll
метод 'replaceAll' добавляется в прототип строки. Это означает, что он будет доступен для всех строковых объектов/литералы.
например.
var output = "test this".replaceAll('this', 'that'); //output is 'test that'. output = output.replaceAll('that', 'this'); //output is 'test this'
скажем, вы хотите заменить все ' 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Я пытался думать о чем-то более простом, чем изменение прототипа строки.
замена одинарных кавычек:
function JavaScriptEncode(text){ text = text.replace(/'/g,''') // More encode here if required return text; }
/ / цикл его, пока число вхождений не доходит до 0. Или просто скопировать / вставить
function replaceAll(find, replace, str) { while( str.indexOf(find) > -1) { str = str.replace(find, replace); } 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) }почти два раза так же быстро, как и способ.
как отметил в комментарии здесь, это не будет работать, если ваш
omitпеременная содержитplace, например:replaceAll("string", "s", "ss"), потому что он всегда сможет заменить другое вхождение слова.есть еще один jsperf с вариантами на моей рекурсивной замене, которые идут еще быстрее (http://jsperf.com/replace-all-vs-split-join/12)!
- обновление 27 июля 2017: похоже, что RegExp теперь имеет самую высокую производительность в недавно выпущенном Chrome 59.
str = str.replace(new RegExp("abc", 'g'), "");работали лучше для меня, чем ответов. так что
new RegExp("abc", 'g')создает регулярное выражение, которое соответствует всем вхождениям ('g'флаг) текста ("abc"). Вторая часть-это то, что заменяется, в вашем случае пустой строкой ("").str- это строка, и мы должны переопределить его, какreplace(...)только возвращает результат, но не перекрывает. В некоторых случаях вы можете использовать это.
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; }
Если то, что вы хотите найти, уже находится в строке, и у вас нет эскейпера регулярных выражений, вы можете использовать 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'));
используя
RegExpна JavaScript может сделать работу для вас, просто сделать что-то вроде ниже:var str ="Test abc test test abc test test test abc test test abc"; str = str.replace(/abc/g, '');если вы думаете о повторном использовании, создайте функцию, чтобы сделать это для вас, но это не рекомендуется, так как это только одна линейная функция, но опять же, если вы сильно используете это, вы можете написать что-то вроде этого:
String.prototype.replaceAll = String.prototype.replaceAll || function(string, replaced) { return this.replace(new RegExp(string, 'g'), replaced); };и просто используйте его в своем коде снова и снова, как показано ниже:
var str ="Test abc test test abc test test test abc test test abc"; str = str.replaceAll('abc', '');но, как я уже упоминал ранее, это не сделает огромный разница в терминах строк для записи или производительности, только кэширование функции может повлиять на некоторую более высокую производительность на длинных строках, а также на хорошую практику сухого кода, если вы хотите повторно использовать.
Мне нравится этот метод (он выглядит немного чище):
text = text.replace(new RegExp("cat","g"), "dog");
если строка содержит подобный шаблон, как
abccc, вы можете использовать это:str.replace(/abc(\s|$)/g, "")
Если вы пытаетесь убедиться, что строка, которую вы ищете, не будет существовать даже после замены, вам нужно использовать цикл.
например:
var str = 'test aabcbc'; str = str.replace(/abc/g, '');после завершения, вы все еще будете иметь "тест 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' и мы хотим удалить все повторяющиеся запятые.
[В таком случае, можно было бы сделать .замените (/,+ / g,','), но в какой-то момент регулярное выражение становится сложным и достаточно медленным, чтобы вместо этого выполнить цикл.]
var string = 'Test abc Test abc Test abc Test abc' string = string.replace(/abc/g, '') console.log(string)
вы можете попробовать объединить эти два мощных метода.
"test abc test test abc".split("abc").join("")надеюсь, что это помогает!
вы можете просто использовать ниже метод
/** * 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); };
хотя люди упоминали об использовании регулярных выражений, но есть лучший подход, если вы хотите заменить текст, независимо от регистр текста. Как в верхнем или нижнем регистре. Синтаксис
//Consider below example originalString.replace(/stringToBeReplaced/gi, ''); //Output will be all the occurrences removed irrespective of casing.вы можете сослаться на подробный пример здесь.
просто следуйте этому регулярному выражению oneliner, добавляя чувствительность к регистру, поэтому, если вы делаете "ABC", он будет действовать так же, как и для "abc".
str = str.replace(/abc/gi, "");
просто добавить
/gdocument.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глобальные
следующая функция работает для меня:
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");просто скопируйте и вставьте этот код в консоль браузера для тестирования.
Я использую 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'
Comments