У меня есть эта строка:
"Test abc test test abc test test test abc test test abc"
Выполнение:
str = str.replace('abc', '');
кажется, только удалить первое вхождение abc
в строке выше.
Как я могу заменить все вхождения этого?
javascript
string
replace
Нажмите Upvote
источник
источник
aba
вababa
сca
, что приводит вы ожидаете?caba
?abca
?cca
?String.prototype.replaceAll()
поставляется в Safari 13.1 и теперь в Firefox Nightly и Chrome Dev и Canary, а также будет поставляться в Firefox 77 и Chrome 85. Он еще не документирован в MDN, но github.com/tc39/proposal-string-replaceall#high-level-api имеет объяснение: «Если searchValue является строкой,String.prototype.replaceAll
заменяет все вхождения searchValue (как если бы.split(searchValue).join(replaceValue)
использовалось глобальное и правильно экранированное регулярное выражение). Если searchValue является неглобальным регулярным выражением,String.prototype.replaceAll
генерируется исключение »Ответы:
Примечание: не используйте это в коде, критичном к производительности.
В качестве альтернативы регулярным выражениям для простой литеральной строки, вы можете использовать
Общая картина
Раньше это было быстрее в некоторых случаях, чем при использовании
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
функцию, и он станет таким же читабельным, как и все остальное. Поскольку производительность неплохая, нет причин избегать этого решения.В ответ на комментарий:
В ответ на комментарий Click Upvote вы можете упростить его еще больше:
Примечание. Регулярные выражения содержат специальные (мета) символы, и поэтому опасно слепо передавать аргумент в
find
функции выше без предварительной обработки для экранирования этих символов. Это описано в Mozilla Developer Network «s Guide JavaScript на регулярных выражениях , где они представляют следующую функцию полезности (которая изменилась , по крайней мере в два раза , так как этот ответ был изначально написано, так что не забудьте проверить сайт MDN для потенциальных обновлений):Таким образом, чтобы сделать
replaceAll()
вышеописанную функцию более безопасной, ее можно изменить на следующую, если вы также включитеescapeRegExp
:источник
function replaceAll(find, replace,str) { var re = new RegExp(find, 'g'); str = str.replace(re, replace); return str; }
replaceAll
реализации является то, что она не будет работать, еслиfind
содержит метасимволы.Для полноты картины я задумался о том, какой метод я должен использовать для этого. Есть два основных способа сделать это, как предлагают другие ответы на этой странице.
Примечание. Как правило, расширение встроенных прототипов в JavaScript обычно не рекомендуется. Я предоставляю в качестве расширений прототипа String просто в целях иллюстрации, демонстрируя различные реализации гипотетического стандартного метода на
String
встроенном прототипе.Реализация на основе регулярных выражений
Разделение и объединение (функциональная) реализация
Не зная слишком много о том, как регулярные выражения работают за кулисами с точки зрения эффективности, я склонялся к расколу и присоединялся к реализации в прошлом, не задумываясь о производительности. Когда я задумался о том, что было более эффективно и по какой причине, я использовал это как предлог для выяснения.
На моем компьютере с Chrome Windows 8 реализация на основе регулярных выражений является самой быстрой , а реализация разбиения и объединения выполняется на 53% медленнее . Это означает, что регулярные выражения в два раза быстрее для ввода lorem ipsum, который я использовал.
Проверьте этот тест, запустив эти две реализации друг против друга.
Как отмечается в комментарии ниже @ThomasLeduc и других, может быть проблема с реализацией на основе регулярных выражений, если она
search
содержит определенные символы, которые зарезервированы как специальные символы в регулярных выражениях . Реализация предполагает, что вызывающая сторона будет избегать строки заранее или будет передавать только те строки, которые не имеют символов в таблице в регулярных выражениях (MDN).MDN также предоставляет реализацию, позволяющую избежать наших строк. Было бы хорошо, если бы это также было стандартизировано
RegExp.escape(str)
, но, увы, его не существует:Мы могли бы вызывать
escapeRegExp
в нашейString.prototype.replaceAll
реализации, однако я не уверен, насколько это повлияет на производительность (потенциально даже для строк, для которых экранирование не требуется, как для всех буквенно-цифровых строк).источник
Использование регулярного выражения с установленным
g
флагом заменит все:Смотрите здесь также
источник
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
так просто и, вероятно, более производительным.Вот функция-прототип строки, основанная на принятом ответе:
РЕДАКТИРОВАТЬ
Если у вас
find
будут специальные символы, вам нужно их избежать:Скрипка: 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;
Обновить:
Уже несколько поздно для обновления, но так как я просто наткнулся на этот вопрос и заметил, что мой предыдущий ответ не тот, которым я доволен. Поскольку вопрос касался замены одного слова, невероятно, что никто не думал об использовании границ слов (
\b
).Это простое регулярное выражение, которое в большинстве случаев избегает замены частей слов. Тем не менее, тире
-
все еще считается границей слова. Поэтому в этом случае можно использовать условные выражения, чтобы избежать замены строк, таких какcool-cat
:в основном, этот вопрос такой же, как и здесь: Javascript заменяет «» на «»
@ Майк, проверь ответ, который я там дал ... regexp - не единственный способ заменить несколько вхождений подстроки, это далеко не так. Думай гибко, думай о разделении!
В качестве альтернативы, чтобы предотвратить замену частей слова - что будет делать и одобренный ответ! Вы можете обойти эту проблему, используя регулярные выражения, которые, я признаю, несколько более сложны и, как следствие, тоже немного медленнее:
Вывод такой же, как принятый ответ, однако с использованием выражения / cat / g в этой строке:
Ой, действительно, это, вероятно, не то, что вы хотите. Что же тогда? ИМХО, регулярное выражение, которое заменяет только «условно». (то есть не часть слова), вот так:
Я думаю, это отвечает вашим потребностям. Конечно, это не полная защита, но этого должно быть достаточно, чтобы вы начали. Я бы порекомендовал прочитать еще на этих страницах. Это окажется полезным в совершенствовании этого выражения для удовлетворения ваших конкретных потребностей.
http://www.javascriptkit.com/jsref/regexp.shtml
http://www.regular-expressions.info
Заключительное дополнение:
Учитывая, что этот вопрос по-прежнему получает много просмотров, я подумал, что мог бы добавить пример
.replace
использования с функцией обратного вызова. В этом случае это значительно упрощает выражение и обеспечивает еще большую гибкость, например, замену на правильную прописную букву или замену обоихcat
и сразуcats
:источник
Сопоставить с глобальным регулярным выражением:
источник
Для замены однократного использования:
Для замены несколько раз используйте:
источник
replace(/\n/g, '<br/>')
Это самые распространенные и читаемые методы.
Способ 1:
Способ 2:
Способ 3:
Способ 4:
Вывод:
источник
Или попробуйте функцию replaceAll отсюда:
Какие полезные методы JavaScript расширяют встроенные объекты?
РЕДАКТИРОВАТЬ: разъяснения о заменеВсе наличие
Метод replaceAll добавлен в прототип String. Это означает, что он будет доступен для всех строковых объектов / литералов.
Например
источник
Использование
RegExp
в JavaScript может помочь вам, просто сделайте что-то вроде приведенного ниже кода, не забывайте,/g
после чего выделяется глобальное :Если вы думаете о повторном использовании, создайте функцию, которая сделает это за вас, но это не рекомендуется, поскольку это всего лишь одна строчная функция, но, опять же, если вы интенсивно ее используете, вы можете написать что-то вроде этого:
и просто используйте его в своем коде снова и снова, как показано ниже:
Но, как я упоминал ранее, это не будет иметь большого значения с точки зрения написания строк или производительности, только кэширование функции может повлиять на более высокую производительность на длинных строках, а также на хорошую практику DRY-кода, если вы захотите использовать повторно.
источник
Скажем, вы хотите заменить все «abc» на «x»:
Я пытался придумать что-то более простое, чем модификация прототипа строки.
источник
Используйте регулярное выражение:
источник
Замена одинарных кавычек:
источник
// зациклить его, пока число вхождений не достигнет 0. ИЛИ просто скопировать / вставить
источник
.indexOf
в переменной и используйте эту переменную в качестве второго параметра.indexOf
(минус длина ключевого слова плюс длина строки замены).работал лучше для меня, чем приведенные выше ответы. поэтому
new RegExp("abc", 'g')
создает RegExp, который соответствует всему вхождению ('g'
флагу) текста ("abc"
). Вторая часть - это то, что заменяется в вашем случае пустой строкой (""
).str
это строка, и мы должны переопределить ее, так какreplace(...)
просто возвращает результат, но не переопределяет. В некоторых случаях вы можете использовать это.источник
Это самая быстрая версия, которая не использует регулярные выражения .
Пересмотренный jsperf
Это почти в два раза быстрее, чем метод split и join.
Как указано в комментарии здесь, это не будет работать, если ваша
omit
переменная содержитplace
, как в:,replaceAll("string", "s", "ss")
потому что она всегда сможет заменить другое вхождение слова.На моей рекурсивной замене есть еще один jsperf с вариантами, которые идут еще быстрее ( http://jsperf.com/replace-all-vs-split-join/12 )!
источник
if(place.replace(omit) === omit) {
No match, поэтому можно безопасно использовать замену цикла} else {
Match, поэтому используйте другой метод, например split и join}
Представление
Сегодня 27.12.2019 я выполняю тесты на macOS v10.13.6 (High Sierra) для выбранных решений.
Выводы
str.replace(/abc/g, '');
( C ) является хорошим кросс-браузер быстрое решение для всех строк.split-join
( A, B ) илиreplace
( C, D ), быстрыеwhile
( E, F, G, H ), являются медленными - обычно в ~ 4 раза медленнее для маленьких строк и примерно в ~ 3000 раз (!) Медленнее для длинных строкЯ также создаю свое собственное решение. Похоже, что в настоящее время это самый короткий вопрос, который выполняет работу с вопросом:
Показать фрагмент кода
подробности
Тесты проводились на Chrome 79.0, Safari 13.0.4 и Firefox 71.0 (64 бит). Тесты
RA
иRB
использование рекурсии. РезультатыКороткая строка - 55 символов
Вы можете запустить тесты на своем компьютере ЗДЕСЬ . Результаты для Chrome:
Длинная строка: 275 000 символов
Рекурсивные решения РА и РБ дает
Для персонажей 1M они даже ломают Chrome
Я пытаюсь выполнить тесты для 1М символов для других решений, но E, F, G, H отнимает столько времени, что браузер просит меня разбить скрипт, поэтому я сокращаю тестовую строку до 275К символов. Вы можете запустить тесты на своем компьютере ЗДЕСЬ . Результаты для Chrome
Код, используемый в тестах
Показать фрагмент кода
источник
Если то, что вы хотите найти, уже находится в строке, и вы не имеете под рукой regex escaper, вы можете использовать join / split:
источник
источник
Мне нравится этот метод (выглядит немного чище):
источник
Самый простой способ сделать это без использования регулярных выражений - это разделить и объединить, как показано здесь:
источник
http://jsfiddle.net/ANHR9/
источник
источник
Если строка содержит похожий шаблон, например
abccc
, вы можете использовать это:источник
Предыдущие ответы слишком сложны. Просто используйте функцию замены следующим образом:
Пример:
источник
Если вы пытаетесь гарантировать, что искомая строка не будет существовать даже после замены, вам нужно использовать цикл.
Например:
После завершения у вас все еще будет «test abc»!
Самый простой цикл для решения этой проблемы:
Но это запускает замену дважды для каждого цикла. Возможно (рискуя быть отвергнутым), что может быть объединено для немного более эффективной, но менее читаемой формы:
Это может быть особенно полезно при поиске дублирующих строк.
Например, если у нас есть «a ,,, b» и мы хотим удалить все повторяющиеся запятые.
[В этом случае можно сделать .replace (/, + / g, ','), но в какой-то момент регулярное выражение становится сложным и достаточно медленным, чтобы выполнять цикл.]
источник
Хотя люди упоминали об использовании регулярных выражений, но есть лучший подход, если вы хотите заменить текст независимо от случая текста. Как прописные или строчные. Используйте ниже синтаксис
Вы можете сослаться на подробный пример здесь .
источник
Вы можете просто использовать метод ниже
источник
Просто добавь
/g
в
/g
означает глобальныйисточник