Related
Given a string:
s = "Test abc test test abc test test test abc test test abc";
This seems to only remove the first occurrence of abc in the string above:
s = s.replace('abc', '');
How do I replace all occurrences of it?
As of August 2020: Modern browsers have support for the String.replaceAll() method defined by the ECMAScript 2021 language specification.
For older/legacy browsers:
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
Here is how this answer evolved:
str = str.replace(/abc/g, '');
In response to comment "what's if 'abc' is passed as a variable?":
var find = 'abc';
var re = new RegExp(find, 'g');
str = str.replace(re, '');
In response to Click Upvote's comment, you could simplify it even more:
function replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
}
Note: Regular expressions contain special (meta) characters, and as such it is dangerous to blindly pass an argument in the find function above without pre-processing it to escape those characters. This is covered in the Mozilla Developer Network's JavaScript Guide on Regular Expressions, where they present the following utility function (which has changed at least twice since this answer was originally written, so make sure to check the MDN site for potential updates):
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
So in order to make the replaceAll() function above safer, it could be modified to the following if you also include escapeRegExp:
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
For the sake of completeness, I got to thinking about which method I should use to do this. There are basically two ways to do this as suggested by the other answers on this page.
Note: In general, extending the built-in prototypes in JavaScript is generally not recommended. I am providing as extensions on the String prototype simply for purposes of illustration, showing different implementations of a hypothetical standard method on the String built-in prototype.
Regular Expression Based Implementation
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
Split and Join (Functional) Implementation
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.split(search).join(replacement);
};
Not knowing too much about how regular expressions work behind the scenes in terms of efficiency, I tended to lean toward the split and join implementation in the past without thinking about performance. When I did wonder which was more efficient, and by what margin, I used it as an excuse to find out.
On my Chrome Windows 8 machine, the regular expression based implementation is the fastest, with the split and join implementation being 53% slower. Meaning the regular expressions are twice as fast for the lorem ipsum input I used.
Check out this benchmark running these two implementations against each other.
As noted in the comment below by #ThomasLeduc and others, there could be an issue with the regular expression-based implementation if search contains certain characters which are reserved as special characters in regular expressions. The implementation assumes that the caller will escape the string beforehand or will only pass strings that are without the characters in the table in Regular Expressions (MDN).
MDN also provides an implementation to escape our strings. It would be nice if this was also standardized as RegExp.escape(str), but alas, it does not exist:
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}
We could call escapeRegExp within our String.prototype.replaceAll implementation, however, I'm not sure how much this will affect the performance (potentially even for strings for which the escape is not needed, like all alphanumeric strings).
In the latest versions of most popular browsers, you can use replaceAll
as shown here:
let result = "1 abc 2 abc 3".replaceAll("abc", "xyz");
// `result` is "1 xyz 2 xyz 3"
But check Can I use or another compatibility table first to make sure the browsers you're targeting have added support for it first.
For Node.js and compatibility with older/non-current browsers:
Note: Don't use the following solution in performance critical code.
As an alternative to regular expressions for a simple literal string, you could use
str = "Test abc test test abc test...".split("abc").join("");
The general pattern is
str.split(search).join(replacement)
This used to be faster in some cases than using replaceAll and a regular expression, but that doesn't seem to be the case anymore in modern browsers.
Benchmark: https://jsben.ch/TZYzj
Conclusion:
If you have a performance-critical use case (e.g., processing hundreds of strings), use the regular expression method. But for most typical use cases, this is well worth not having to worry about special characters.
Here's a string prototype function based on the accepted answer:
String.prototype.replaceAll = function(find, replace) {
var str = this;
return str.replace(new RegExp(find, 'g'), replace);
};
If your find contains special characters then you need to escape them:
String.prototype.replaceAll = function(find, replace) {
var str = this;
return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};
Fiddle: http://jsfiddle.net/cdbzL/
Use word boundaries (\b)
'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"
This is a simple regex that avoids replacing parts of words in most cases. However, a dash - is still considered a word boundary. So conditionals can be used in this case to avoid replacing strings like 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"
Basically, this question is the same as the question here:
Replace " ' " with " '' " in JavaScript
Regexp isn't the only way to replace multiple occurrences of a substring, far from it. Think flexible, think split!
var newText = "the cat looks like a cat".split('cat').join('dog');
Alternatively, to prevent replacing word parts—which the approved answer will do, too! You can get around this issue using regular expressions that are, I admit, somewhat more complex and as an upshot of that, a tad slower, too:
var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
The output is the same as the accepted answer, however, using the /cat/g expression on this string:
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" ??
Oops indeed, this probably isn't what you want. What is, then? IMHO, a regex that only replaces 'cat' conditionally (i.e., not part of a word), like so:
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"
My guess is, this meets your needs. It's not foolproof, of course, but it should be enough to get you started. I'd recommend reading some more on these pages. This'll prove useful in perfecting this expression to meet your specific needs.
RegExp (regular expression) object
Regular-Expressions.info
Here is an example of .replace used with a callback function. In this case, it dramatically simplifies the expression and provides even more flexibility, like replacing with correct capitalisation or replacing both cat and cats in one go:
'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
These are the most common and readable methods.
var str = "Test abc test test abc test test test abc test test abc"
Method 1:
str = str.replace(/abc/g, "replaced text");
Method 2:
str = str.split("abc").join("replaced text");
Method 3:
str = str.replace(new RegExp("abc", "g"), "replaced text");
Method 4:
while(str.includes("abc")){
str = str.replace("abc", "replaced text");
}
Output:
console.log(str);
// Test replaced text test test replaced text test test test replaced text test test replaced text
Match against a global regular expression:
anotherString = someString.replace(/cat/g, 'dog');
For replacing a single time, use:
var res = str.replace('abc', "");
For replacing multiple times, use:
var res = str.replace(/abc/g, "");
str = str.replace(/abc/g, '');
Or try the replaceAll method, as recommended in this answer:
str = str.replaceAll('abc', '');
or:
var search = 'abc';
str = str.replaceAll(search, '');
EDIT: Clarification about replaceAll availability
The replaceAll method is added to String's prototype. This means it will be available for all string objects/literals.
Example:
var output = "test this".replaceAll('this', 'that'); // output is 'test that'.
output = output.replaceAll('that', 'this'); // output is 'test this'
Using RegExp in JavaScript could do the job for you. Just simply do something like below code, and don't forget the /g after which standout for global:
var str ="Test abc test test abc test test test abc test test abc";
str = str.replace(/abc/g, '');
If you think of reuse, create a function to do that for you, but it's not recommended as it's only one line function. But again, if you heavily use this, you can write something like this:
String.prototype.replaceAll = String.prototype.replaceAll || function(string, replaced) {
return this.replace(new RegExp(string, 'g'), replaced);
};
And simply use it in your code over and over like below:
var str ="Test abc test test abc test test test abc test test abc";
str = str.replaceAll('abc', '');
But as I mention earlier, it won't make a huge difference in terms of lines to be written or performance. Only caching the function may affect some faster performance on long strings and is also a good practice of DRY code if you want to reuse.
Say you want to replace all the 'abc' with '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
I was trying to think about something more simple than modifying the string prototype.
Use a regular expression:
str.replace(/abc/g, '');
Performance
Today 27.12.2019 I perform tests on macOS v10.13.6 (High Sierra) for the chosen solutions.
Conclusions
The str.replace(/abc/g, ''); (C) is a good cross-browser fast solution for all strings.
Solutions based on split-join (A,B) or replace (C,D) are fast
Solutions based on while (E,F,G,H) are slow - usually ~4 times slower for small strings and about ~3000 times (!) slower for long strings
The recurrence solutions (RA,RB) are slow and do not work for long strings
I also create my own solution. It looks like currently it is the shortest one which does the question job:
str.split`abc`.join``
str = "Test abc test test abc test test test abc test test abc";
str = str.split`abc`.join``
console.log(str);
Details
The tests were performed on Chrome 79.0, Safari 13.0.4 and Firefox 71.0 (64 bit). The tests RA and RB use recursion. Results
Short string - 55 characters
You can run tests on your machine HERE. Results for Chrome:
Long string: 275 000 characters
The recursive solutions RA and RB gives
RangeError: Maximum call stack size exceeded
For 1M characters they even break Chrome
I try to perform tests for 1M characters for other solutions, but E,F,G,H takes so much time that browser ask me to break script so I shrink test string to 275K characters. You can run tests on your machine HERE. Results for Chrome
Code used in tests
var t="Test abc test test abc test test test abc test test abc"; // .repeat(5000)
var log = (version,result) => console.log(`${version}: ${result}`);
function A(str) {
return str.split('abc').join('');
}
function B(str) {
return str.split`abc`.join``; // my proposition
}
function C(str) {
return str.replace(/abc/g, '');
}
function D(str) {
return str.replace(new RegExp("abc", "g"), '');
}
function E(str) {
while (str.indexOf('abc') !== -1) { str = str.replace('abc', ''); }
return str;
}
function F(str) {
while (str.indexOf('abc') !== -1) { str = str.replace(/abc/, ''); }
return str;
}
function G(str) {
while(str.includes("abc")) { str = str.replace('abc', ''); }
return str;
}
// src: https://stackoverflow.com/a/56989553/860099
function H(str)
{
let i = -1
let find = 'abc';
let newToken = '';
if (!str)
{
if ((str == null) && (find == null)) return newToken;
return str;
}
while ((
i = str.indexOf(
find, i >= 0 ? i + newToken.length : 0
)) !== -1
)
{
str = str.substring(0, i) +
newToken +
str.substring(i + find.length);
}
return str;
}
// src: https://stackoverflow.com/a/22870785/860099
function RA(string, prevstring) {
var omit = 'abc';
var place = '';
if (prevstring && string === prevstring)
return string;
prevstring = string.replace(omit, place);
return RA(prevstring, string)
}
// src: https://stackoverflow.com/a/26107132/860099
function RB(str) {
var find = 'abc';
var 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) + RB(st2, find, replace);
}
}
return str;
}
log('A ', A(t));
log('B ', B(t));
log('C ', C(t));
log('D ', D(t));
log('E ', E(t));
log('F ', F(t));
log('G ', G(t));
log('H ', H(t));
log('RA', RA(t)); // use reccurence
log('RB', RB(t)); // use reccurence
<p style="color:red">This snippet only presents codes used in tests. It not perform test itself!<p>
Replacing single quotes:
function JavaScriptEncode(text){
text = text.replace(/'/g,''')
// More encode here if required
return text;
}
Using
str = str.replace(new RegExp("abc", 'g'), "");
worked better for me than the previous answers. So new RegExp("abc", 'g') creates a regular expression what matches all occurrences ('g' flag) of the text ("abc"). The second part is what gets replaced to, in your case empty string ("").
str is the string, and we have to override it, as replace(...) just returns result, but not overrides. In some cases you might want to use that.
This is the fastest version that doesn't use regular expressions.
Revised jsperf
replaceAll = function(string, omit, place, prevstring) {
if (prevstring && string === prevstring)
return string;
prevstring = string.replace(omit, place);
return replaceAll(prevstring, omit, place, string)
}
It is almost twice as fast as the split and join method.
As pointed out in a comment here, this will not work if your omit variable contains place, as in: replaceAll("string", "s", "ss"), because it will always be able to replace another occurrence of the word.
There is another jsperf with variants on my recursive replace that go even faster (http://jsperf.com/replace-all-vs-split-join/12)!
Update July 27th 2017: It looks like RegExp now has the fastest performance in the recently released Chrome 59.
Loop it until number occurrences comes to 0, like this:
function replaceAll(find, replace, str) {
while (str.indexOf(find) > -1) {
str = str.replace(find, replace);
}
return str;
}
If what you want to find is already in a string, and you don't have a regex escaper handy, you can use 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'));
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;
}
I like this method (it looks a little cleaner):
text = text.replace(new RegExp("cat","g"), "dog");
String.prototype.replaceAll - ECMAScript 2021
The new String.prototype.replaceAll() method returns a new string with all matches of a pattern replaced by a replacement. The pattern can be either a string or a RegExp, and the replacement can be either a string or a function to be called for each match.
const message = 'dog barks meow meow';
const messageFormatted = message.replaceAll('meow', 'woof')
console.log(messageFormatted);
Of course in 2021 the right answer is:
String.prototype.replaceAll()
console.log(
'Change this and this for me'.replaceAll('this','that') // Normal case
);
console.log(
'aaaaaa'.replaceAll('aa','a') // Challenged case
);
If you don't want to deal with replace() + RegExp.
But what if the browser is from before 2020?
In this case we need polyfill (forcing older browsers to support new features) (I think for a few years will be necessary).
I could not find a completely right method in answers. So I suggest this function that will be defined as a polyfill.
My suggested options for replaceAll polyfill:
replaceAll polyfill (with global-flag error) (more principled version)
if (!String.prototype.replaceAll) { // Check if the native function not exist
Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
configurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)
value: function(search, replace) { // Set the function by closest input names (For good info in consoles)
return this.replace( // Using native String.prototype.replace()
Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?
? search.global // Is the RegEx global?
? search // So pass it
: function(){throw new TypeError('replaceAll called with a non-global RegExp argument')}() // If not throw an error
: RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\$&"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExp
replace); // passing second argument
}
});
}
replaceAll polyfill (With handling global-flag missing by itself) (my first preference) - Why?
if (!String.prototype.replaceAll) { // Check if the native function not exist
Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
configurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)
value: function(search, replace) { // Set the function by closest input names (For good info in consoles)
return this.replace( // Using native String.prototype.replace()
Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?
? search.global // Is the RegEx global?
? search // So pass it
: RegExp(search.source, /\/([a-z]*)$/.exec(search.toString())[1] + 'g') // If not, make a global clone from the RegEx
: RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\$&"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExp
replace); // passing second argument
}
});
}
Minified (my first preference):
if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\$&"),"g"),replace)}})}
Try it:
if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\$&"),"g"),replace)}})}
console.log(
'Change this and this for me'.replaceAll('this','that')
); // Change that and that for me
console.log(
'aaaaaa'.replaceAll('aa','a')
); // aaa
console.log(
'{} (*) (*) (RegEx) (*) (\*) (\\*) [reserved characters]'.replaceAll('(*)','X')
); // {} X X (RegEx) X X (\*) [reserved characters]
console.log(
'How (replace) (XX) with $1?'.replaceAll(/(xx)/gi,'$$1')
); // How (replace) ($1) with $1?
console.log(
'Here is some numbers 1234567890 1000000 123123.'.replaceAll(/\d+/g,'***')
); // Here is some numbers *** *** *** and need to be replaced.
console.log(
'Remove numbers under 233: 236 229 711 200 5'.replaceAll(/\d+/g, function(m) {
return parseFloat(m) < 233 ? '' : m
})
); // Remove numbers under 233: 236 711
console.log(
'null'.replaceAll(null,'x')
); // x
// The difference between My first preference and the original:
// Now in 2022 with browsers > 2020 it should throw an error (But possible it be changed in future)
// console.log(
// 'xyz ABC abc ABC abc xyz'.replaceAll(/abc/i,'')
// );
// Browsers < 2020:
// xyz xyz
// Browsers > 2020
// TypeError: String.prototype.replaceAll called with a non-global RegExp
Browser support:
Internet Explorer 9 and later (rested on Internet Explorer 11).
All other browsers (after 2012).
The result is the same as the native replaceAll in case of the first argument input is:
null, undefined, Object, Function, Date, ... , RegExp, Number, String, ...
Ref: 22.1.3.19 String.prototype.replaceAll ( searchValue, replaceValue)
+ RegExp Syntax
Important note: As some professionals mention it, many of recursive functions that suggested in answers, will return the wrong result. (Try them with the challenged case of the above snippet.)
Maybe some tricky methods like .split('searchValue').join('replaceValue') or some well managed functions give same result, but definitely with much lower performance than native replaceAll() / polyfill replaceAll() / replace() + RegExp
Other methods of polyfill assignment
Naive, but supports even older browsers (be better to avoid)
For example, we can support IE7+ too, by not using Object.defineProperty() and using my old naive assignment method:
if (!String.prototype.replaceAll) {
String.prototype.replaceAll = function(search, replace) { // <-- Naive method for assignment
// ... (Polyfill code Here)
}
}
And it should work well for basic uses on IE7+.
But as here #sebastian-simon explained about, that can make secondary problems in case of more advanced uses. E.g.:
for (var k in 'hi') console.log(k);
// 0
// 1
// replaceAll <-- ?
Fully trustable, but heavy
In fact, my suggested option is a little optimistic. Like we trusted the environment (browser and Node.js), it is definitely for around 2012-2021. Also it is a standard/famous one, so it does not require any special consideration.
But there can be even older browsers or some unexpected problems, and polyfills still can support and solve more possible environment problems. So in case we need the maximum support that is possible, we can use polyfill libraries like:
https://polyfill.io/
Specially for replaceAll:
<script src="https://polyfill.io/v3/polyfill.min.js?features=String.prototype.replaceAll"></script>
The simplest way to do this without using any regular expression is split and join, like the code here:
var str = "Test abc test test abc test test test abc test test abc";
console.log(str.split('abc').join(''));
var str = "ff ff f f a de def";
str = str.replace(/f/g,'');
alert(str);
http://jsfiddle.net/ANHR9/
while (str.indexOf('abc') !== -1)
{
str = str.replace('abc', '');
}
If the string contains a similar pattern like abccc, you can use this:
str.replace(/abc(\s|$)/g, "")
As of August 2020 there is a Stage 4 proposal to ECMAScript that adds the replaceAll method to String.
It's now supported in Chrome 85+, Edge 85+, Firefox 77+, Safari 13.1+.
The usage is the same as the replace method:
String.prototype.replaceAll(searchValue, replaceValue)
Here's an example usage:
'Test abc test test abc test.'.replaceAll('abc', 'foo'); // -> 'Test foo test test foo test.'
It's supported in most modern browsers, but there exist polyfills:
core-js
es-shims
It is supported in the V8 engine behind an experimental flag --harmony-string-replaceall.
Read more on the V8 website.
The previous answers are way too complicated. Just use the replace function like this:
str.replace(/your_regex_pattern/g, replacement_string);
Example:
var str = "Test abc test test abc test test test abc test test abc";
var res = str.replace(/[abc]+/g, "");
console.log(res);
After several trials and a lot of fails, I found that the below function seems to be the best all-rounder when it comes to browser compatibility and ease of use. This is the only working solution for older browsers that I found. (Yes, even though old browser are discouraged and outdated, some legacy applications still make heavy use of OLE browsers (such as old Visual Basic 6 applications or Excel .xlsm macros with forms.)
Anyway, here's the simple function.
function replaceAll(str, match, replacement){
return str.split(match).join(replacement);
}
If you are trying to ensure that the string you are looking for won't exist even after the replacement, you need to use a loop.
For example:
var str = 'test aabcbc';
str = str.replace(/abc/g, '');
When complete, you will still have 'test abc'!
The simplest loop to solve this would be:
var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
str.replace(/abc/g, '');
}
But that runs the replacement twice for each cycle. Perhaps (at risk of being voted down) that can be combined for a slightly more efficient but less readable form:
var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!
This can be particularly useful when looking for duplicate strings.
For example, if we have 'a,,,b' and we wish to remove all duplicate commas.
[In that case, one could do .replace(/,+/g,','), but at some point the regex gets complex and slow enough to loop instead.]
Given a string:
s = "Test abc test test abc test test test abc test test abc";
This seems to only remove the first occurrence of abc in the string above:
s = s.replace('abc', '');
How do I replace all occurrences of it?
As of August 2020: Modern browsers have support for the String.replaceAll() method defined by the ECMAScript 2021 language specification.
For older/legacy browsers:
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
Here is how this answer evolved:
str = str.replace(/abc/g, '');
In response to comment "what's if 'abc' is passed as a variable?":
var find = 'abc';
var re = new RegExp(find, 'g');
str = str.replace(re, '');
In response to Click Upvote's comment, you could simplify it even more:
function replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
}
Note: Regular expressions contain special (meta) characters, and as such it is dangerous to blindly pass an argument in the find function above without pre-processing it to escape those characters. This is covered in the Mozilla Developer Network's JavaScript Guide on Regular Expressions, where they present the following utility function (which has changed at least twice since this answer was originally written, so make sure to check the MDN site for potential updates):
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
So in order to make the replaceAll() function above safer, it could be modified to the following if you also include escapeRegExp:
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
For the sake of completeness, I got to thinking about which method I should use to do this. There are basically two ways to do this as suggested by the other answers on this page.
Note: In general, extending the built-in prototypes in JavaScript is generally not recommended. I am providing as extensions on the String prototype simply for purposes of illustration, showing different implementations of a hypothetical standard method on the String built-in prototype.
Regular Expression Based Implementation
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
Split and Join (Functional) Implementation
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.split(search).join(replacement);
};
Not knowing too much about how regular expressions work behind the scenes in terms of efficiency, I tended to lean toward the split and join implementation in the past without thinking about performance. When I did wonder which was more efficient, and by what margin, I used it as an excuse to find out.
On my Chrome Windows 8 machine, the regular expression based implementation is the fastest, with the split and join implementation being 53% slower. Meaning the regular expressions are twice as fast for the lorem ipsum input I used.
Check out this benchmark running these two implementations against each other.
As noted in the comment below by #ThomasLeduc and others, there could be an issue with the regular expression-based implementation if search contains certain characters which are reserved as special characters in regular expressions. The implementation assumes that the caller will escape the string beforehand or will only pass strings that are without the characters in the table in Regular Expressions (MDN).
MDN also provides an implementation to escape our strings. It would be nice if this was also standardized as RegExp.escape(str), but alas, it does not exist:
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}
We could call escapeRegExp within our String.prototype.replaceAll implementation, however, I'm not sure how much this will affect the performance (potentially even for strings for which the escape is not needed, like all alphanumeric strings).
In the latest versions of most popular browsers, you can use replaceAll
as shown here:
let result = "1 abc 2 abc 3".replaceAll("abc", "xyz");
// `result` is "1 xyz 2 xyz 3"
But check Can I use or another compatibility table first to make sure the browsers you're targeting have added support for it first.
For Node.js and compatibility with older/non-current browsers:
Note: Don't use the following solution in performance critical code.
As an alternative to regular expressions for a simple literal string, you could use
str = "Test abc test test abc test...".split("abc").join("");
The general pattern is
str.split(search).join(replacement)
This used to be faster in some cases than using replaceAll and a regular expression, but that doesn't seem to be the case anymore in modern browsers.
Benchmark: https://jsben.ch/TZYzj
Conclusion:
If you have a performance-critical use case (e.g., processing hundreds of strings), use the regular expression method. But for most typical use cases, this is well worth not having to worry about special characters.
Here's a string prototype function based on the accepted answer:
String.prototype.replaceAll = function(find, replace) {
var str = this;
return str.replace(new RegExp(find, 'g'), replace);
};
If your find contains special characters then you need to escape them:
String.prototype.replaceAll = function(find, replace) {
var str = this;
return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};
Fiddle: http://jsfiddle.net/cdbzL/
Use word boundaries (\b)
'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"
This is a simple regex that avoids replacing parts of words in most cases. However, a dash - is still considered a word boundary. So conditionals can be used in this case to avoid replacing strings like 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"
Basically, this question is the same as the question here:
Replace " ' " with " '' " in JavaScript
Regexp isn't the only way to replace multiple occurrences of a substring, far from it. Think flexible, think split!
var newText = "the cat looks like a cat".split('cat').join('dog');
Alternatively, to prevent replacing word parts—which the approved answer will do, too! You can get around this issue using regular expressions that are, I admit, somewhat more complex and as an upshot of that, a tad slower, too:
var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
The output is the same as the accepted answer, however, using the /cat/g expression on this string:
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" ??
Oops indeed, this probably isn't what you want. What is, then? IMHO, a regex that only replaces 'cat' conditionally (i.e., not part of a word), like so:
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"
My guess is, this meets your needs. It's not foolproof, of course, but it should be enough to get you started. I'd recommend reading some more on these pages. This'll prove useful in perfecting this expression to meet your specific needs.
RegExp (regular expression) object
Regular-Expressions.info
Here is an example of .replace used with a callback function. In this case, it dramatically simplifies the expression and provides even more flexibility, like replacing with correct capitalisation or replacing both cat and cats in one go:
'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
These are the most common and readable methods.
var str = "Test abc test test abc test test test abc test test abc"
Method 1:
str = str.replace(/abc/g, "replaced text");
Method 2:
str = str.split("abc").join("replaced text");
Method 3:
str = str.replace(new RegExp("abc", "g"), "replaced text");
Method 4:
while(str.includes("abc")){
str = str.replace("abc", "replaced text");
}
Output:
console.log(str);
// Test replaced text test test replaced text test test test replaced text test test replaced text
Match against a global regular expression:
anotherString = someString.replace(/cat/g, 'dog');
For replacing a single time, use:
var res = str.replace('abc', "");
For replacing multiple times, use:
var res = str.replace(/abc/g, "");
str = str.replace(/abc/g, '');
Or try the replaceAll method, as recommended in this answer:
str = str.replaceAll('abc', '');
or:
var search = 'abc';
str = str.replaceAll(search, '');
EDIT: Clarification about replaceAll availability
The replaceAll method is added to String's prototype. This means it will be available for all string objects/literals.
Example:
var output = "test this".replaceAll('this', 'that'); // output is 'test that'.
output = output.replaceAll('that', 'this'); // output is 'test this'
Using RegExp in JavaScript could do the job for you. Just simply do something like below code, and don't forget the /g after which standout for global:
var str ="Test abc test test abc test test test abc test test abc";
str = str.replace(/abc/g, '');
If you think of reuse, create a function to do that for you, but it's not recommended as it's only one line function. But again, if you heavily use this, you can write something like this:
String.prototype.replaceAll = String.prototype.replaceAll || function(string, replaced) {
return this.replace(new RegExp(string, 'g'), replaced);
};
And simply use it in your code over and over like below:
var str ="Test abc test test abc test test test abc test test abc";
str = str.replaceAll('abc', '');
But as I mention earlier, it won't make a huge difference in terms of lines to be written or performance. Only caching the function may affect some faster performance on long strings and is also a good practice of DRY code if you want to reuse.
Say you want to replace all the 'abc' with '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
I was trying to think about something more simple than modifying the string prototype.
Use a regular expression:
str.replace(/abc/g, '');
Performance
Today 27.12.2019 I perform tests on macOS v10.13.6 (High Sierra) for the chosen solutions.
Conclusions
The str.replace(/abc/g, ''); (C) is a good cross-browser fast solution for all strings.
Solutions based on split-join (A,B) or replace (C,D) are fast
Solutions based on while (E,F,G,H) are slow - usually ~4 times slower for small strings and about ~3000 times (!) slower for long strings
The recurrence solutions (RA,RB) are slow and do not work for long strings
I also create my own solution. It looks like currently it is the shortest one which does the question job:
str.split`abc`.join``
str = "Test abc test test abc test test test abc test test abc";
str = str.split`abc`.join``
console.log(str);
Details
The tests were performed on Chrome 79.0, Safari 13.0.4 and Firefox 71.0 (64 bit). The tests RA and RB use recursion. Results
Short string - 55 characters
You can run tests on your machine HERE. Results for Chrome:
Long string: 275 000 characters
The recursive solutions RA and RB gives
RangeError: Maximum call stack size exceeded
For 1M characters they even break Chrome
I try to perform tests for 1M characters for other solutions, but E,F,G,H takes so much time that browser ask me to break script so I shrink test string to 275K characters. You can run tests on your machine HERE. Results for Chrome
Code used in tests
var t="Test abc test test abc test test test abc test test abc"; // .repeat(5000)
var log = (version,result) => console.log(`${version}: ${result}`);
function A(str) {
return str.split('abc').join('');
}
function B(str) {
return str.split`abc`.join``; // my proposition
}
function C(str) {
return str.replace(/abc/g, '');
}
function D(str) {
return str.replace(new RegExp("abc", "g"), '');
}
function E(str) {
while (str.indexOf('abc') !== -1) { str = str.replace('abc', ''); }
return str;
}
function F(str) {
while (str.indexOf('abc') !== -1) { str = str.replace(/abc/, ''); }
return str;
}
function G(str) {
while(str.includes("abc")) { str = str.replace('abc', ''); }
return str;
}
// src: https://stackoverflow.com/a/56989553/860099
function H(str)
{
let i = -1
let find = 'abc';
let newToken = '';
if (!str)
{
if ((str == null) && (find == null)) return newToken;
return str;
}
while ((
i = str.indexOf(
find, i >= 0 ? i + newToken.length : 0
)) !== -1
)
{
str = str.substring(0, i) +
newToken +
str.substring(i + find.length);
}
return str;
}
// src: https://stackoverflow.com/a/22870785/860099
function RA(string, prevstring) {
var omit = 'abc';
var place = '';
if (prevstring && string === prevstring)
return string;
prevstring = string.replace(omit, place);
return RA(prevstring, string)
}
// src: https://stackoverflow.com/a/26107132/860099
function RB(str) {
var find = 'abc';
var 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) + RB(st2, find, replace);
}
}
return str;
}
log('A ', A(t));
log('B ', B(t));
log('C ', C(t));
log('D ', D(t));
log('E ', E(t));
log('F ', F(t));
log('G ', G(t));
log('H ', H(t));
log('RA', RA(t)); // use reccurence
log('RB', RB(t)); // use reccurence
<p style="color:red">This snippet only presents codes used in tests. It not perform test itself!<p>
Replacing single quotes:
function JavaScriptEncode(text){
text = text.replace(/'/g,''')
// More encode here if required
return text;
}
Using
str = str.replace(new RegExp("abc", 'g'), "");
worked better for me than the previous answers. So new RegExp("abc", 'g') creates a regular expression what matches all occurrences ('g' flag) of the text ("abc"). The second part is what gets replaced to, in your case empty string ("").
str is the string, and we have to override it, as replace(...) just returns result, but not overrides. In some cases you might want to use that.
This is the fastest version that doesn't use regular expressions.
Revised jsperf
replaceAll = function(string, omit, place, prevstring) {
if (prevstring && string === prevstring)
return string;
prevstring = string.replace(omit, place);
return replaceAll(prevstring, omit, place, string)
}
It is almost twice as fast as the split and join method.
As pointed out in a comment here, this will not work if your omit variable contains place, as in: replaceAll("string", "s", "ss"), because it will always be able to replace another occurrence of the word.
There is another jsperf with variants on my recursive replace that go even faster (http://jsperf.com/replace-all-vs-split-join/12)!
Update July 27th 2017: It looks like RegExp now has the fastest performance in the recently released Chrome 59.
Loop it until number occurrences comes to 0, like this:
function replaceAll(find, replace, str) {
while (str.indexOf(find) > -1) {
str = str.replace(find, replace);
}
return str;
}
If what you want to find is already in a string, and you don't have a regex escaper handy, you can use 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'));
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;
}
I like this method (it looks a little cleaner):
text = text.replace(new RegExp("cat","g"), "dog");
String.prototype.replaceAll - ECMAScript 2021
The new String.prototype.replaceAll() method returns a new string with all matches of a pattern replaced by a replacement. The pattern can be either a string or a RegExp, and the replacement can be either a string or a function to be called for each match.
const message = 'dog barks meow meow';
const messageFormatted = message.replaceAll('meow', 'woof')
console.log(messageFormatted);
Of course in 2021 the right answer is:
String.prototype.replaceAll()
console.log(
'Change this and this for me'.replaceAll('this','that') // Normal case
);
console.log(
'aaaaaa'.replaceAll('aa','a') // Challenged case
);
If you don't want to deal with replace() + RegExp.
But what if the browser is from before 2020?
In this case we need polyfill (forcing older browsers to support new features) (I think for a few years will be necessary).
I could not find a completely right method in answers. So I suggest this function that will be defined as a polyfill.
My suggested options for replaceAll polyfill:
replaceAll polyfill (with global-flag error) (more principled version)
if (!String.prototype.replaceAll) { // Check if the native function not exist
Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
configurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)
value: function(search, replace) { // Set the function by closest input names (For good info in consoles)
return this.replace( // Using native String.prototype.replace()
Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?
? search.global // Is the RegEx global?
? search // So pass it
: function(){throw new TypeError('replaceAll called with a non-global RegExp argument')}() // If not throw an error
: RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\$&"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExp
replace); // passing second argument
}
});
}
replaceAll polyfill (With handling global-flag missing by itself) (my first preference) - Why?
if (!String.prototype.replaceAll) { // Check if the native function not exist
Object.defineProperty(String.prototype, 'replaceAll', { // Define replaceAll as a prototype for (Mother/Any) String
configurable: true, writable: true, enumerable: false, // Editable & non-enumerable property (As it should be)
value: function(search, replace) { // Set the function by closest input names (For good info in consoles)
return this.replace( // Using native String.prototype.replace()
Object.prototype.toString.call(search) === '[object RegExp]' // IsRegExp?
? search.global // Is the RegEx global?
? search // So pass it
: RegExp(search.source, /\/([a-z]*)$/.exec(search.toString())[1] + 'g') // If not, make a global clone from the RegEx
: RegExp(String(search).replace(/[.^$*+?()[{|\\]/g, "\\$&"), "g"), // Replace all reserved characters with '\' then make a global 'g' RegExp
replace); // passing second argument
}
});
}
Minified (my first preference):
if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\$&"),"g"),replace)}})}
Try it:
if(!String.prototype.replaceAll){Object.defineProperty(String.prototype,'replaceAll',{configurable:!0,writable:!0,enumerable:!1,value:function(search,replace){return this.replace(Object.prototype.toString.call(search)==='[object RegExp]'?search.global?search:RegExp(search.source,/\/([a-z]*)$/.exec(search.toString())[1]+'g'):RegExp(String(search).replace(/[.^$*+?()[{|\\]/g,"\\$&"),"g"),replace)}})}
console.log(
'Change this and this for me'.replaceAll('this','that')
); // Change that and that for me
console.log(
'aaaaaa'.replaceAll('aa','a')
); // aaa
console.log(
'{} (*) (*) (RegEx) (*) (\*) (\\*) [reserved characters]'.replaceAll('(*)','X')
); // {} X X (RegEx) X X (\*) [reserved characters]
console.log(
'How (replace) (XX) with $1?'.replaceAll(/(xx)/gi,'$$1')
); // How (replace) ($1) with $1?
console.log(
'Here is some numbers 1234567890 1000000 123123.'.replaceAll(/\d+/g,'***')
); // Here is some numbers *** *** *** and need to be replaced.
console.log(
'Remove numbers under 233: 236 229 711 200 5'.replaceAll(/\d+/g, function(m) {
return parseFloat(m) < 233 ? '' : m
})
); // Remove numbers under 233: 236 711
console.log(
'null'.replaceAll(null,'x')
); // x
// The difference between My first preference and the original:
// Now in 2022 with browsers > 2020 it should throw an error (But possible it be changed in future)
// console.log(
// 'xyz ABC abc ABC abc xyz'.replaceAll(/abc/i,'')
// );
// Browsers < 2020:
// xyz xyz
// Browsers > 2020
// TypeError: String.prototype.replaceAll called with a non-global RegExp
Browser support:
Internet Explorer 9 and later (rested on Internet Explorer 11).
All other browsers (after 2012).
The result is the same as the native replaceAll in case of the first argument input is:
null, undefined, Object, Function, Date, ... , RegExp, Number, String, ...
Ref: 22.1.3.19 String.prototype.replaceAll ( searchValue, replaceValue)
+ RegExp Syntax
Important note: As some professionals mention it, many of recursive functions that suggested in answers, will return the wrong result. (Try them with the challenged case of the above snippet.)
Maybe some tricky methods like .split('searchValue').join('replaceValue') or some well managed functions give same result, but definitely with much lower performance than native replaceAll() / polyfill replaceAll() / replace() + RegExp
Other methods of polyfill assignment
Naive, but supports even older browsers (be better to avoid)
For example, we can support IE7+ too, by not using Object.defineProperty() and using my old naive assignment method:
if (!String.prototype.replaceAll) {
String.prototype.replaceAll = function(search, replace) { // <-- Naive method for assignment
// ... (Polyfill code Here)
}
}
And it should work well for basic uses on IE7+.
But as here #sebastian-simon explained about, that can make secondary problems in case of more advanced uses. E.g.:
for (var k in 'hi') console.log(k);
// 0
// 1
// replaceAll <-- ?
Fully trustable, but heavy
In fact, my suggested option is a little optimistic. Like we trusted the environment (browser and Node.js), it is definitely for around 2012-2021. Also it is a standard/famous one, so it does not require any special consideration.
But there can be even older browsers or some unexpected problems, and polyfills still can support and solve more possible environment problems. So in case we need the maximum support that is possible, we can use polyfill libraries like:
https://polyfill.io/
Specially for replaceAll:
<script src="https://polyfill.io/v3/polyfill.min.js?features=String.prototype.replaceAll"></script>
The simplest way to do this without using any regular expression is split and join, like the code here:
var str = "Test abc test test abc test test test abc test test abc";
console.log(str.split('abc').join(''));
var str = "ff ff f f a de def";
str = str.replace(/f/g,'');
alert(str);
http://jsfiddle.net/ANHR9/
while (str.indexOf('abc') !== -1)
{
str = str.replace('abc', '');
}
If the string contains a similar pattern like abccc, you can use this:
str.replace(/abc(\s|$)/g, "")
As of August 2020 there is a Stage 4 proposal to ECMAScript that adds the replaceAll method to String.
It's now supported in Chrome 85+, Edge 85+, Firefox 77+, Safari 13.1+.
The usage is the same as the replace method:
String.prototype.replaceAll(searchValue, replaceValue)
Here's an example usage:
'Test abc test test abc test.'.replaceAll('abc', 'foo'); // -> 'Test foo test test foo test.'
It's supported in most modern browsers, but there exist polyfills:
core-js
es-shims
It is supported in the V8 engine behind an experimental flag --harmony-string-replaceall.
Read more on the V8 website.
The previous answers are way too complicated. Just use the replace function like this:
str.replace(/your_regex_pattern/g, replacement_string);
Example:
var str = "Test abc test test abc test test test abc test test abc";
var res = str.replace(/[abc]+/g, "");
console.log(res);
After several trials and a lot of fails, I found that the below function seems to be the best all-rounder when it comes to browser compatibility and ease of use. This is the only working solution for older browsers that I found. (Yes, even though old browser are discouraged and outdated, some legacy applications still make heavy use of OLE browsers (such as old Visual Basic 6 applications or Excel .xlsm macros with forms.)
Anyway, here's the simple function.
function replaceAll(str, match, replacement){
return str.split(match).join(replacement);
}
If you are trying to ensure that the string you are looking for won't exist even after the replacement, you need to use a loop.
For example:
var str = 'test aabcbc';
str = str.replace(/abc/g, '');
When complete, you will still have 'test abc'!
The simplest loop to solve this would be:
var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
str.replace(/abc/g, '');
}
But that runs the replacement twice for each cycle. Perhaps (at risk of being voted down) that can be combined for a slightly more efficient but less readable form:
var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!
This can be particularly useful when looking for duplicate strings.
For example, if we have 'a,,,b' and we wish to remove all duplicate commas.
[In that case, one could do .replace(/,+/g,','), but at some point the regex gets complex and slow enough to loop instead.]
I need to search an array in JavaScript. The search would be for only part of the string to match as the string would have additional components. I would then need to return the successfully matched array element with the full string.
Example:
const windowArray = [ "item", "thing", "id-3-text", "class" ];
I need to search for the array element with "id-" in it and I need to pull the rest of the text in the element as well (i.e. "id-3-text").
How do I do that?
If you're able to use Underscore.js in your project, the _.filter() array function makes this a snap:
// find all strings in array containing 'thi'
var matches = _.filter(
[ 'item 1', 'thing', 'id-3-text', 'class' ],
function( s ) { return s.indexOf( 'thi' ) !== -1; }
);
The iterator function can do whatever you want as long as it returns true for matches. Works great.
Update 2017-12-03:
This is a pretty outdated answer now. Maybe not the most performant option in a large batch, but it can be written a lot more tersely and use native ES6 Array/String methods like .filter() and .includes() now:
// find all strings in array containing 'thi'
const items = ['item 1', 'thing', 'id-3-text', 'class'];
const matches = items.filter(s => s.includes('thi'));
Note: There's no <= IE11 support for String.prototype.includes() (Edge works, mind you), but you're fine with a polyfill, or just fall back to indexOf().
People here are making this waaay too difficult. Just do the following...
myArray.findIndex(element => element.includes("substring"))
findIndex() is an ES6 higher order method that iterates through the elements of an array and returns the index of the first element that matches some criteria (provided as a function). In this case I used ES6 syntax to declare the higher order function. element is the parameter of the function (which could be any name) and the fat arrow declares what follows as an anonymous function (which does not need to be wrapped in curly braces unless it takes up more than one line).
Within findIndex() I used the very simple includes() method to check if the current element includes the substring that you want.
The simplest way to get the substrings array from the given array is to use filter and includes:
myArray.filter(element => element.includes("substring"));
The above one will return an array of substrings.
myArray.find(element => element.includes("substring"));
The above one will return the first result element from the array.
myArray.findIndex(element => element.includes("substring"));
The above one will return the index of the first result element from the array.
In your specific case, you can do it just with a boring old counter:
var index, value, result;
for (index = 0; index < windowArray.length; ++index) {
value = windowArray[index];
if (value.substring(0, 3) === "id-") {
// You've found it, the full text is in `value`.
// So you might grab it and break the loop, although
// really what you do having found it depends on
// what you need.
result = value;
break;
}
}
// Use `result` here, it will be `undefined` if not found
But if your array is sparse, you can do it more efficiently with a properly-designed for..in loop:
var key, value, result;
for (key in windowArray) {
if (windowArray.hasOwnProperty(key) && !isNaN(parseInt(key, 10))) {
value = windowArray[key];
if (value.substring(0, 3) === "id-") {
// You've found it, the full text is in `value`.
// So you might grab it and break the loop, although
// really what you do having found it depends on
// what you need.
result = value;
break;
}
}
}
// Use `result` here, it will be `undefined` if not found
Beware naive for..in loops that don't have the hasOwnProperty and !isNaN(parseInt(key, 10)) checks; here's why.
Off-topic:
Another way to write
var windowArray = new Array ("item","thing","id-3-text","class");
is
var windowArray = ["item","thing","id-3-text","class"];
...which is less typing for you, and perhaps (this bit is subjective) a bit more easily read. The two statements have exactly the same result: A new array with those contents.
Just search for the string in plain old indexOf
arr.forEach(function(a){
if (typeof(a) == 'string' && a.indexOf('curl')>-1) {
console.log(a);
}
});
The simplest vanilla javascript code to achieve this is
var windowArray = ["item", "thing", "id-3-text", "class", "3-id-text"];
var textToFind = "id-";
//if you only want to match id- as prefix
var matches = windowArray.filter(function(windowValue){
if(windowValue) {
return (windowValue.substring(0, textToFind.length) === textToFind);
}
}); //["id-3-text"]
//if you want to match id- string exists at any position
var matches = windowArray.filter(function(windowValue){
if(windowValue) {
return windowValue.indexOf(textToFind) >= 0;
}
}); //["id-3-text", "3-id-text"]
For a fascinating examination of some of the alternatives and their efficiency, see John Resig's recent posts:
JavaScript Trie Performance Analysis
Revised JavaScript Dictionary Search
(The problem discussed there is slightly different, with the haystack elements being prefixes of the needle and not the other way around, but most solutions are easy to adapt.)
let url = item.product_image_urls.filter(arr=>arr.match("homepage")!==null)
Filter array with string match. It is easy and one line code.
ref:
In javascript, how do you search an array for a substring match
The solution given here is generic unlike the solution 4556343#4556343, which requires a previous parse to identify a string with which to join(), that is not a component of any of the array strings.
Also, in that code /!id-[^!]*/ is more correctly, /![^!]*id-[^!]*/ to suit the question parameters:
"search an array ..." (of strings or numbers and not functions, arrays, objects, etc.)
"for only part of the string to match " (match can be anywhere)
"return the ... matched ... element" (singular, not ALL, as in "... the ... elementS")
"with the full string" (include the quotes)
... NetScape / FireFox solutions (see below for a JSON solution):
javascript: /* "one-liner" statement solution */
alert(
["x'!x'\"id-2",'\' "id-1 "', "item","thing","id-3-text","class" ] .
toSource() . match( new RegExp(
'[^\\\\]("([^"]|\\\\")*' + 'id-' + '([^"]|\\\\")*[^\\\\]")' ) ) [1]
);
or
javascript:
ID = 'id-' ;
QS = '([^"]|\\\\")*' ; /* only strings with escaped double quotes */
RE = '[^\\\\]("' +QS+ ID +QS+ '[^\\\\]")' ;/* escaper of escaper of escaper */
RE = new RegExp( RE ) ;
RA = ["x'!x'\"id-2",'\' "id-1 "', "item","thing","id-3-text","class" ] ;
alert(RA.toSource().match(RE)[1]) ;
displays "x'!x'\"id-2".
Perhaps raiding the array to find ALL matches is 'cleaner'.
/* literally (? backslash star escape quotes it!) not true, it has this one v */
javascript: /* purely functional - it has no ... =! */
RA = ["x'!x'\"id-2",'\' "id-1 "', "item","thing","id-3-text","class" ] ;
function findInRA(ra,id){
ra.unshift(void 0) ; /* cheat the [" */
return ra . toSource() . match( new RegExp(
'[^\\\\]"' + '([^"]|\\\\")*' + id + '([^"]|\\\\")*' + '[^\\\\]"' ,
'g' ) ) ;
}
alert( findInRA( RA, 'id-' ) . join('\n\n') ) ;
displays:
"x'!x'\"id-2"
"' \"id-1 \""
"id-3-text"
Using, JSON.stringify():
javascript: /* needs prefix cleaning */
RA = ["x'!x'\"id-2",'\' "id-1 "', "item","thing","id-3-text","class" ] ;
function findInRA(ra,id){
return JSON.stringify( ra ) . match( new RegExp(
'[^\\\\]"([^"]|\\\\")*' + id + '([^"]|\\\\")*[^\\\\]"' ,
'g' ) ) ;
}
alert( findInRA( RA, 'id-' ) . join('\n\n') ) ;
displays:
["x'!x'\"id-2"
,"' \"id-1 \""
,"id-3-text"
wrinkles:
The "unescaped" global RegExp is /[^\]"([^"]|\")*id-([^"]|\")*[^\]"/g with the \ to be found literally. In order for ([^"]|\")* to match strings with all "'s escaped as \", the \ itself must be escaped as ([^"]|\\")*. When this is referenced as a string to be concatenated with id-, each \ must again be escaped, hence ([^"]|\\\\")*!
A search ID that has a \, *, ", ..., must also be escaped via .toSource() or JSON or ... .
null search results should return '' (or "" as in an EMPTY string which contains NO "!) or [] (for all search).
If the search results are to be incorporated into the program code for further processing, then eval() is necessary, like eval('['+findInRA(RA,ID).join(',')+']').
--------------------------------------------------------------------------------
Digression:
Raids and escapes? Is this code conflicted?
The semiotics, syntax and semantics of /* it has no ... =! */ emphatically elucidates the escaping of quoted literals conflict.
Does "no =" mean:
"no '=' sign" as in javascript:alert('\x3D') (Not! Run it and see that there is!),
"no javascript statement with the assignment operator",
"no equal" as in "nothing identical in any other code" (previous code solutions demonstrate there are functional equivalents),
...
Quoting on another level can also be done with the immediate mode javascript protocol URI's below. (// commentaries end on a new line (aka nl, ctrl-J, LineFeed, ASCII decimal 10, octal 12, hex A) which requires quoting since inserting a nl, by pressing the Return key, invokes the URI.)
javascript:/* a comment */ alert('visible') ;
javascript:// a comment ; alert( 'not' ) this is all comment %0A;
javascript:// a comment %0A alert('visible but %\0A is wrong ') // X %0A
javascript:// a comment %0A alert('visible but %'+'0A is a pain to type') ;
Note: Cut and paste any of the javascript: lines as an immediate mode URI (at least, at most?, in FireFox) to use first javascript: as a URI scheme or protocol and the rest as JS labels.
I've created a simple to use library (ss-search) which is designed to handle objects, but could also work in your case:
search(windowArray.map(x => ({ key: x }), ["key"], "SEARCH_TEXT").map(x => x.key)
The advantage of using this search function is that it will normalize the text before executing the search to return more accurate results.
Another possibility is
var res = /!id-[^!]*/.exec("!"+windowArray.join("!"));
return res && res[0].substr(1);
that IMO may make sense if you can have a special char delimiter (here i used "!"), the array is constant or mostly constant (so the join can be computed once or rarely) and the full string isn't much longer than the prefix searched for.
I think this may help you. I had a similar issue. If your array looks like this:
var array = ["page1","1973","Jimmy"];
You can do a simple "for" loop to return the instance in the array when you get a match.
var c;
for (i = 0; i < array.length; i++) {
if (array[i].indexOf("page") > -1){
c = i;}
}
We create an empty variable, c to host our answer.
We then loop through the array to find where the array object (e.g. "page1") matches our indexOf("page"). In this case, it's 0 (the first result)
Happy to expand if you need further support.
Use this function for search substring Item.
function checkItem(arrayItem, searchItem) {
return arrayItem.findIndex(element => element.includes(searchItem)) >= 0
}
function getItem(arrayItem, getItem) {
return arrayItem.filter(element => element.includes(getItem))
}
var arrayItem = ["item","thing","id-3-text","class"];
console.log(checkItem(arrayItem, "id-"))
console.log(checkItem(arrayItem, "vivek"))
console.log(getItem(arrayItem, "id-"))
Here's your expected snippet which gives you the array of all the matched values:
var windowArray = new Array ("item","thing","id-3-text","class");
var result = [];
windowArray.forEach(val => {
if(val && val.includes('id-')) {
result.push(val);
}
});
console.log(result);
this worked for me .
const filterData = this.state.data2.filter(item=>((item.name.includes(text)) || (item.surname.includes(text)) || (item.email.includes(text)) || (item.userId === Number(text))) ) ;
I've got a data-123 string.
How can I remove data- from the string while leaving the 123?
var ret = "data-123".replace('data-','');
console.log(ret); //prints: 123
Docs.
For all occurrences to be discarded use:
var ret = "data-123".replace(/data-/g,'');
PS: The replace function returns a new string and leaves the original string unchanged, so use the function return value after the replace() call.
This doesn't have anything to do with jQuery. You can use the JavaScript replace function for this:
var str = "data-123";
str = str.replace("data-", "");
You can also pass a regex to this function. In the following example, it would replace everything except numerics:
str = str.replace(/[^0-9\.]+/g, "");
You can use "data-123".replace('data-','');, as mentioned, but as replace() only replaces the FIRST instance of the matching text, if your string was something like "data-123data-" then
"data-123data-".replace('data-','');
will only replace the first matching text. And your output will be "123data-"
DEMO
So if you want all matches of text to be replaced in string you have to use a regular expression with the g flag like that:
"data-123data-".replace(/data-/g,'');
And your output will be "123"
DEMO2
You can use slice(), if you will know in advance how many characters need slicing off the original string. It returns characters between a given start point to an end point.
string.slice(start, end);
Here are some examples showing how it works:
var mystr = ("data-123").slice(5); // This just defines a start point so the output is "123"
var mystr = ("data-123").slice(5,7); // This defines a start and an end so the output is "12"
Demo
Plain old JavaScript will suffice - jQuery is not necessary for such a simple task:
var myString = "data-123";
var myNewString = myString.replace("data-", "");
See: .replace() docs on MDN for additional information and usage.
1- If is the sequences into your string:
let myString = "mytest-text";
let myNewString = myString.replace("mytest-", "");
the answer is text
2- if you whant to remove the first 3 characters:
"mytest-text".substring(3);
the answer is est-text
Ex:-
var value="Data-123";
var removeData=value.replace("Data-","");
alert(removeData);
Hopefully this will work for you.
Performance
Today 2021.01.14 I perform tests on MacOs HighSierra 10.13.6 on Chrome v87, Safari v13.1.2 and Firefox v84 for chosen solutions.
Results
For all browsers
solutions Ba, Cb, and Db are fast/fastest for long strings
solutions Ca, Da are fast/fastest for short strings
solutions Ab and E are slow for long strings
solutions Ba, Bb and F are slow for short strings
Details
I perform 2 tests cases:
short string - 10 chars - you can run it HERE
long string - 1 000 000 chars - you can run it HERE
Below snippet presents solutions
Aa
Ab
Ba
Bb
Ca
Cb
Da
Db
E
F
// https://stackoverflow.com/questions/10398931/how-to-strToRemove-text-from-a-string
// https://stackoverflow.com/a/10398941/860099
function Aa(str,strToRemove) {
return str.replace(strToRemove,'');
}
// https://stackoverflow.com/a/63362111/860099
function Ab(str,strToRemove) {
return str.replaceAll(strToRemove,'');
}
// https://stackoverflow.com/a/23539019/860099
function Ba(str,strToRemove) {
let re = strToRemove.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // regexp escape char
return str.replace(new RegExp(re),'');
}
// https://stackoverflow.com/a/63362111/860099
function Bb(str,strToRemove) {
let re = strToRemove.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // regexp escape char
return str.replaceAll(new RegExp(re,'g'),'');
}
// https://stackoverflow.com/a/27098801/860099
function Ca(str,strToRemove) {
let start = str.indexOf(strToRemove);
return str.slice(0,start) + str.slice(start+strToRemove.length, str.length);
}
// https://stackoverflow.com/a/27098801/860099
function Cb(str,strToRemove) {
let start = str.search(strToRemove);
return str.slice(0,start) + str.slice(start+strToRemove.length, str.length);
}
// https://stackoverflow.com/a/23181792/860099
function Da(str,strToRemove) {
let start = str.indexOf(strToRemove);
return str.substr(0, start) + str.substr(start + strToRemove.length);
}
// https://stackoverflow.com/a/23181792/860099
function Db(str,strToRemove) {
let start = str.search(strToRemove);
return str.substr(0, start) + str.substr(start + strToRemove.length);
}
// https://stackoverflow.com/a/49857431/860099
function E(str,strToRemove) {
return str.split(strToRemove).join('');
}
// https://stackoverflow.com/a/45406624/860099
function F(str,strToRemove) {
var n = str.search(strToRemove);
while (str.search(strToRemove) > -1) {
n = str.search(strToRemove);
str = str.substring(0, n) + str.substring(n + strToRemove.length, str.length);
}
return str;
}
let str = "data-123";
let strToRemove = "data-";
[Aa,Ab,Ba,Bb,Ca,Cb,Da,Db,E,F].map( f=> console.log(`${f.name.padEnd(2,' ')} ${f(str,strToRemove)}`));
This shippet only presents functions used in performance tests - it not perform tests itself!
And here are example results for chrome
This little function I made has always worked for me :)
String.prototype.deleteWord = function (searchTerm) {
var str = this;
var n = str.search(searchTerm);
while (str.search(searchTerm) > -1) {
n = str.search(searchTerm);
str = str.substring(0, n) + str.substring(n + searchTerm.length, str.length);
}
return str;
}
// Use it like this:
var string = "text is the cool!!";
string.deleteWord('the'); // Returns text is cool!!
I know it is not the best, but It has always worked for me :)
str.split('Yes').join('No');
This will replace all the occurrences of that specific string from original string.
I was used to the C# (Sharp) String.Remove method.
In Javascript, there is no remove function for string, but there is substr function.
You can use the substr function once or twice to remove characters from string.
You can make the following function to remove characters at start index to the end of string, just like the c# method first overload String.Remove(int startIndex):
function Remove(str, startIndex) {
return str.substr(0, startIndex);
}
and/or you also can make the following function to remove characters at start index and count, just like the c# method second overload String.Remove(int startIndex, int count):
function Remove(str, startIndex, count) {
return str.substr(0, startIndex) + str.substr(startIndex + count);
}
and then you can use these two functions or one of them for your needs!
Example:
alert(Remove("data-123", 0, 5));
Output: 123
Using match() and Number() to return a number variable:
Number(("data-123").match(/\d+$/));
// strNum = 123
Here's what the statement above does...working middle-out:
str.match(/\d+$/) - returns an array containing matches to any length of numbers at the end of str. In this case it returns an array containing a single string item ['123'].
Number() - converts it to a number type. Because the array returned from .match() contains a single element Number() will return the number.
Update 2023
There are many ways to solve this problem, but I believe this is the simplest:
const newString = string.split("data-").pop();
console.log(newString); /// 123
For doing such a thing there are a lot of different ways. A further way could be the following:
let str = 'data-123';
str = str.split('-')[1];
console.log('The remaining string is:\n' + str);
Basically the above code splits the string at the '-' char into two array elements and gets the second one, that is the one with the index 1, ignoring the first array element at the 0 index.
The following is one liner version:
console.log('The remaining string is:\n' + 'data-123'.split('-')[1]);
Another possible approach would be to add a method to the String prototype as follows:
String.prototype.remove = function (s){return this.replace(s,'')}
// After that it will be used like this:
a = 'ktkhkiksk kiksk ktkhkek kcklkekaknk kmkekskskakgkekk';
a = a.remove('k');
console.log(a);
Notice the above snippet will allow to remove only the first instance of the string you are interested to remove. But you can improve it a bit as follows:
String.prototype.removeAll = function (s){return this.replaceAll(s,'')}
// After that it will be used like this:
a = 'ktkhkiksk kiksk ktkhkek kcklkekaknk kmkekskskakgkekk';
a = a.removeAll('k');
console.log(a);
The above snippet instead will remove all instances of the string passed to the method.
Of course you don't need to implement the functions into the prototype of the String object: you can implement them as simple functions too if you wish (I will show the remove all function, for the other you will need to use just replace instead of replaceAll, so it is trivial to implement):
function strRemoveAll(s,r)
{
return s.replaceAll(r,'');
}
// you can use it as:
let a = 'ktkhkiksk kiksk ktkhkek kcklkekaknk kmkekskskakgkekk'
b = strRemoveAll (a,'k');
console.log(b);
Of course much more is possible.
Another way to replace all instances of a string is to use the new (as of August 2020) String.prototype.replaceAll() method.
It accepts either a string or RegEx as its first argument, and replaces all matches found with its second parameter, either a string or a function to generate the string.
As far as support goes, at time of writing, this method has adoption in current versions of all major desktop browsers* (even Opera!), except IE. For mobile, iOS SafariiOS 13.7+, Android Chromev85+, and Android Firefoxv79+ are all supported as well.
* This includes Edge/ Chrome v85+, Firefox v77+, Safari 13.1+, and Opera v71+
It'll take time for users to update to supported browser versions, but now that there's wide browser support, time is the only obstacle.
References:
MDN
Can I Use - Current Browser Support Information
TC39 Proposal Repo for .replaceAll()
You can test your current browser in the snippet below:
//Example coutesy of MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll
const p = 'The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?';
const regex = /dog/gi;
try {
console.log(p.replaceAll(regex, 'ferret'));
// expected output: "The quick brown fox jumps over the lazy ferret. If the ferret reacted, was it really lazy?"
console.log(p.replaceAll('dog', 'monkey'));
// expected output: "The quick brown fox jumps over the lazy monkey. If the monkey reacted, was it really lazy?"
console.log('Your browser is supported!');
} catch (e) {
console.log('Your browser is unsupported! :(');
}
.as-console-wrapper: {
max-height: 100% !important;
}
Make sure that if you are replacing strings in a loop that you initiate a new Regex in each iteration. As of 9/21/21, this is still a known issue with Regex essentially missing every other match. This threw me for a loop when I encountered this the first time:
yourArray.forEach((string) => {
string.replace(new RegExp(__your_regex__), '___desired_replacement_value___');
})
If you try and do it like so, don't be surprised if only every other one works
let reg = new RegExp('your regex');
yourArray.forEach((string) => {
string.replace(reg, '___desired_replacement_value___');
})
The replace function returns the new string with the replaces, but if there weren't any words to replace, then the original string is returned. Is there a way to know whether it actually replaced anything apart from comparing the result with the original string?
A simple option is to check for matches before you replace:
var regex = /i/g;
var newStr = str;
var replaced = str.search(regex) >= 0;
if(replaced){
newStr = newStr.replace(regex, '!');
}
If you don't want that either, you can abuse the replace callback to achieve that in a single pass:
var replaced = false;
var newStr = str.replace(/i/g, function(token){replaced = true; return '!';});
As a workaround you can implement your own callback function that will set a flag and do the replacement. The replacement argument of replace can accept functions.
Comparing the before and after strings is the easiest way to check if it did anything, there's no intrinsic support in String.replace().
[contrived example of how '==' might fail deleted because it was wrong]
Javascript replace is defected by design. Why? It has no compatibility with string replacement in callback.
For example:
"ab".replace(/(a)(b)/, "$1$2")
> "ab"
We want to verify that replace is done in single pass. I was imagine something like:
"ab".replace(/(a)(b)/, "$1$2", function replacing() { console.log('ok'); })
> "ab"
Real variant:
"ab".replace(/(a)(b)/, function replacing() {
console.log('ok');
return "$1$2";
})
> ok
> "$1$2"
But function replacing is designed to receive $0, $1, $2, offset, string and we have to fight with replacement "$1$2". The solution is:
"ab".replace(/(a)(b)/, function replacing() {
console.log('ok');
// arguments are $0, $1, ..., offset, string
return Array.from(arguments).slice(1, -2)
.reduce(function (pattern, match, index) {
// '$1' from strings like '$11 $12' shouldn't be replaced.
return pattern.replace(
new RegExp("\\$" + (index + 1) + "(?=[^\\d]|$)", "g"),
match
);
}, "$1$2");
});
> ok
> "ab"
This solution is not perfect. String replacement itself has its own WATs. For example:
"a".replace(/(a)/, "$01")
> "a"
"a".replace(/(a)/, "$001")
> "$001"
If you want to care about compatibility you have to read spec and implement all its craziness.
If your replace has a different length from the searched text, you can check the length of the string before and after. I know, this is a partial response, valid only on a subset of the problem.
OR
You can do a search. If the search is successfull you do a replace on the substring starting with the found index and then recompose the string. This could be slower because you are generating 3 strings instead of 2.
var test = "Hellllo";
var index = test.search(/ll/);
if (index >= 0) {
test = test.substr(0, index - 1) + test.substr(index).replace(/ll/g, "tt");
}
alert(test);
While this will require multiple operations, using .test() may suffice:
const regex = /foo/;
const yourString = 'foo bar';
if (regex.test(yourString)) {
console.log('yourString contains regex');
// Go ahead and do whatever else you'd like.
}
The test() method executes a search for a match between a regular expression and a specified string. Returns true or false.
With indexOf you can check wether a string contains another string.
Seems like you might want to use that.
have a look at string.match() or string.search()
After doing any RegExp method, read RegExp.lastMatch property:
/^$/.test(''); //Clear RegExp.lastMatch first, Its value will be ''
'abcd'.replace(/bc/,'12');
if(RegExp.lastMatch !== '')
console.log('has been replaced');
else
console.log('not replaced');