87

Is there an easy equivalent to this in JavaScript?

$find = array("<", ">", "\n");
$replace = array("&lt;", "&gt;", "<br/>");
$textarea = str_replace($find, $replace, $textarea); 

This is using PHP's str_replace, which allows you to use an array of words to look for and replace. Can I do something like this using JavaScript / jQuery?

...
var textarea = $(this).val();
// string replace here
$("#output").html(textarea);
...
Ry-
226k56 gold badges496 silver badges504 bronze badges
asked Feb 21, 2011 at 18:00
3
  • 3
    Just for clarification, are you doing this to escape html? Commented Feb 21, 2011 at 18:11
  • Multiple replace instead of single replace? If you want to do anything like that efficiently, you need a regular expression. That is not what the selected answer is doing. Commented May 4, 2018 at 19:55
  • See this post, I think it is what you are looking for Commented Jul 17, 2018 at 22:37

19 Answers 19

94

You could extend the String object with your own function that does what you need (useful if there's ever missing functionality):

String.prototype.replaceArray = function(find, replace) {
 var replaceString = this;
 for (var i = 0; i < find.length; i++) {
 replaceString = replaceString.replace(find[i], replace[i]);
 }
 return replaceString;
};

For global replace you could use regex:

String.prototype.replaceArray = function(find, replace) {
 var replaceString = this;
 var regex; 
 for (var i = 0; i < find.length; i++) {
 regex = new RegExp(find[i], "g");
 replaceString = replaceString.replace(regex, replace[i]);
 }
 return replaceString;
};

To use the function it'd be similar to your PHP example:

var textarea = $(this).val();
var find = ["<", ">", "\n"];
var replace = ["&lt;", "&gt;", "<br/>"];
textarea = textarea.replaceArray(find, replace);
answered Feb 21, 2011 at 18:31

13 Comments

Thanks bob, assuming this is using prototype(?) would you know how to do this using jQuery?
@Tim This is regular JavaScript, no extra library needed. JavaScript is a prototypal language which means every object has a prototype it inherits from. Adding to the object's prototype is simply a way to extend all such objects.
"tar pit".replaceArray(['tar', 'pit'], ['capitol', 'house']) // "cahouseol house"
This solution doesn't work for the following: String: "The cat hits the dog" find array: ['cat', 'dog'] replace array: ['dog, 'cat']
@derekdreery The function neither work for strings that contains RegExp characters, for example: find array ["(", ")"] replace array ["[", "]"]
|
59

Common Mistake

Nearly all answers on this page use cumulative replacement and thus suffer the same flaw where replacement strings are themselves subject to replacement. Here are a couple examples where this pattern fails (h/t @KurokiKaze @derekdreery):

function replaceCumulative(str, find, replace) {
 for (var i = 0; i < find.length; i++)
 str = str.replace(new RegExp(find[i],"g"), replace[i]);
 return str;
};
// Fails in some cases:
console.log( replaceCumulative( "tar pit", ['tar','pit'], ['capitol','house'] ) );
console.log( replaceCumulative( "you & me", ['you','me'], ['me','you'] ) );

Solution

function replaceBulk( str, findArray, replaceArray ){
 var i, regex = [], map = {}; 
 for( i=0; i<findArray.length; i++ ){ 
 regex.push( findArray[i].replace(/([-[\]{}()*+?.\\^$|#,])/g,'\\1ドル') );
 map[findArray[i]] = replaceArray[i]; 
 }
 regex = regex.join('|');
 str = str.replace( new RegExp( regex, 'g' ), function(matched){
 return map[matched];
 });
 return str;
}
// Test:
console.log( replaceBulk( "tar pit", ['tar','pit'], ['capitol','house'] ) );
console.log( replaceBulk( "you & me", ['you','me'], ['me','you'] ) );

Note:

This is a more compatible variation of @elchininet's solution, which uses map() and Array.indexOf() and thus won't work in IE8 and older.

@elchininet's implementation holds truer to PHP's str_replace(), because it also allows strings as find/replace parameters, and will use the first find array match if there are duplicates (my version will use the last). I didn't accept strings in this implementation because that case is already handled by JS's built-in String.replace().

answered Jun 21, 2016 at 16:18

7 Comments

@StephenM.Harris Cool answer, you have noticed too that almost all answers in the page are using cumulative replacements.
This doesn't work when replacing characters like brackets. For example, it's common to use ((placeholder)) style tags and this will replace it those ((undefined)) jsfiddle.net/oLfmeaa6/1
@MacroMan fixed! Had to update the regex that escapes special regex chars (which just sounds bug-prone :D). Thanks for pointing this out!
Love this code. Addendum: I changed it to replaceBulk(str, obj) {var findArray = Object.keys(obj), var replaceArray = Object.values(obj);....} So, I can pass in a simple hash-object of {"x":"y"...} replacements. Seems easier to maintain.
@HoldOffHunger The double array inputs are truer to PHP's str_replace() this was intended to emulate -- but that aside I prefer the object input too! Just keep in mind Object.values will not work in IE without a polyfill.
|
24
text = text.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br/>');
Ry-
226k56 gold badges496 silver badges504 bronze badges
answered Feb 21, 2011 at 18:06

2 Comments

This is not "at once". Basically the same as this "one-liner": text = text.replace(foo); text = text.replace(bar);
@Beejor To be fair, the accepted answer is not "at once" either, it just hides the subsequent replacements behind a function.
13

A more visual approach:

String.prototype.htmlProtect = function() {
 var replace_map;
 replace_map = {
 '\n': '<br />',
 '<': '&lt;',
 '>': '&gt;'
 };
 return this.replace(/[<>\n]/g, function(match) { // be sure to add every char in the pattern
 return replace_map[match];
 });
};

and this is how you call it:

var myString = "<b>tell me a story, \n<i>bro'</i>";
var myNewString = myString.htmlProtect();
// &lt;b&gt;tell me a story, <br />&lt;i&gt;bro'&lt;/i&gt;
answered Apr 15, 2013 at 16:25

1 Comment

Error: this.replace is not a function !
12

You could use the replace method of the String object with a function in the second parameter to avoid replacing a string that was previously replaced:

First Method (using a find and replace Object)

var findreplace = {"<" : "&lt;", ">" : "&gt;", "\n" : "<br/>"};
textarea = textarea.replace(new RegExp("(" + Object.keys(findreplace).map(function(i){return i.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")}).join("|") + ")", "g"), function(s){ return findreplace[s]});

jsfiddle

Second method (using two arrays, find and replace)

var find = ["<", ">", "\n"];
var replace = ["&lt;", "&gt;", "<br/>"];
textarea = textarea.replace(new RegExp("(" + find.map(function(i){return i.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")}).join("|") + ")", "g"), function(s){ return replace[find.indexOf(s)]});

jsfiddle

Desired function:

function str_replace($f, $r, $s){
 return $s.replace(new RegExp("(" + $f.map(function(i){return i.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")}).join("|") + ")", "g"), function(s){ return $r[$f.indexOf(s)]});
}
$textarea = str_replace($find, $replace, $textarea);

EDIT

This function admits a String or an Array as parameters:

function str_replace($f, $r, $s){
 return $s.replace(new RegExp("(" + (typeof($f) === "string" ? $f.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&") : $f.map(function(i){return i.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")}).join("|")) + ")", "g"), typeof($r) === "string" ? $r : typeof($f) === "string" ? $r[0] : function(i){ return $r[$f.indexOf(i)]});
}
answered Jan 1, 2016 at 22:24

7 Comments

looks cool, but not work in some cases :( . e.g. {'[0-1]':'NUM'}
Hi @Soyoes, tell me in what cases it fails and I'll try to fix it.
Hi @Soyoes, I've tested it and it works: [jsfiddle] (jsfiddle.net/uxv2u9n0)
Hi , I tried something like this {'My':'Your', '[0-1]':'NUM'} with str "My name is Peter, Am 19", using the 1st method.
This method is to search and replace Strings or Array of Strings. It not works with RegExps, if you want to use a RegExp like a search parameter, you need to parse the find Array to convert it into RegExp. I'll give you an example in a couple of minutes.
|
7

A simple forEach loop solves this quite well:

let text = 'the red apple and the green ball';
const toStrip = ['red', 'green'];
toStrip.forEach(x => {
 text = text.replace(x, '');
});
console.log(text);
// logs -> the apple and the ball
answered Apr 28, 2020 at 17:20

Comments

6

The top answer is equivalent to doing:

let text = find.reduce((acc, item, i) => {
 const regex = new RegExp(item, "g");
 return acc.replace(regex, replace[i]);
}, textarea);

Given this:

var textarea = $(this).val();
var find = ["<", ">", "\n"];
var replace = ["&lt;", "&gt;", "<br/>"];

In this case, no imperative programming is going on.

answered Oct 3, 2018 at 9:23

Comments

5

Using ES6: There are many ways to search for strings and replace in JavaScript. One of them is as follow

const findFor = ['<', '>', '\n'];
const replaceWith = ['&lt;', '&gt;', '<br/>'];
const originalString = '<strong>Hello World</strong> \n Let\'s code';
let modifiedString = originalString;
findFor.forEach( (tag, i) => modifiedString = modifiedString.replace(new RegExp(tag, "g"), replaceWith[i]) )
console.log('Original String: ', originalString);
console.log('Modified String: ', modifiedString);

answered Feb 8, 2019 at 7:25

1 Comment

I used this method and it is elegant and works. Unfortunately, YUI compressor 2.4.8 cannot handle the ES6 and crashes.
4

You might want to look into a JS library called phpJS.

It allows you to use the str_replace function similarly to how you would use it in PHP. There are also plenty more php functions "ported" over to JavaScript.

http://phpjs.org/functions/str_replace:527

answered Feb 21, 2011 at 18:48

Comments

4
String.prototype.replaceArray = function (find, replace) {
 var replaceString = this;
 for (var i = 0; i < find.length; i++) {
 // global replacement
 var pos = replaceString.indexOf(find[i]);
 while (pos > -1) {
 replaceString = replaceString.replace(find[i], replace[i]);
 pos = replaceString.indexOf(find[i]);
 }
 }
 return replaceString;
};
var textT = "Hello world,,,,, hello people.....";
var find = [".",","];
var replace = ['2', '5'];
textT = textT.replaceArray(find, replace);
// result: Hello world55555 hello people22222
ElChiniNet
2,9193 gold badges22 silver badges28 bronze badges
answered May 30, 2014 at 12:56

1 Comment

This prototype does not work if you enter these vars: var find = [".",","]; var replace = [',', '.'];
4

const items = {
 '<': '&lt;',
 '>': '&gt;',
 '\n': '<br/>',
}
const re = new RegExp('[' + Object.keys(items).join('') + ']', 'g')
const input = '<foo>\n<bar>'
const output = input.replaceAll(re, key => items[key])
console.log(output)

answered Nov 24, 2021 at 21:05

Comments

2

There is no way to do this in one method call, you'll have to either chain calls together, or write a function that manually does what you need.

var s = "<>\n";
s = s.replace("<", "&lt;");
s = s.replace(">", "&gt;");
s = s.replace("\n", "<br/>");
answered Feb 21, 2011 at 18:07

1 Comment

I like it simple. Was looking for a similar function from php. OK, copy-past - but 3 lines - no a whole prototype function.
2

For the tags, you should be able to just set the content with .text() instead of .html().

Example: http://jsfiddle.net/Phf4u/1/

var textarea = $('textarea').val().replace(/<br\s?\/?>/, '\n');
$("#output").text(textarea);

...or if you just wanted to remove the <br> elements, you could get rid of the .replace(), and temporarily make them DOM elements.

Example: http://jsfiddle.net/Phf4u/2/

var textarea = $('textarea').val();
textarea = $('<div>').html(textarea).find('br').remove().end().html();
$("#output").text(textarea);
answered Feb 21, 2011 at 18:13

Comments

0

A version with an object as a parameter:

String.prototype.strtr = function (replace) {
 keys = Object.keys(replace);
 result = this;
 for (i = 0; i < keys.length; i++) {
 result = result.replace(keys[i], replace[keys[i]]);
 }
 return result;
}
function htmlspecialchars(str) {
 return String(str).strtr({">": "&gt;", "<": "&lt;", "\n": "<br/>"});
}
// usage
text = "<span>spam</span>";
htmlspecialchars(text);
answered Dec 26, 2021 at 2:46

Comments

0

jquery have a solution for that.

var htmlString = $( element).html(); $( element ).text( htmlString );

view here: https://api.jquery.com/html/

answered Mar 3, 2022 at 15:40

Comments

0

wrap all this in a function, you can pass both an array and a string

function str_replace(search,replace,subject) {
if(!Array.isArray(search)){
 subject = subject.replace(new RegExp(search, "g"), replace)
}
else{
 search.forEach( (tag, i) => subject = subject.replace(new RegExp(tag, "g"), replace[i]) )
}
return subject;
}
answered May 10, 2022 at 14:03

Comments

0

Just that!

let v = "Test's <<foo>> ((baAr))";
console.log(v);
const r = ['<', '>', 'a', '\\)', '\\(', '\'' ];
for (var i = r.length - 1; i >= 0; i--) {
 v = v.replace((new RegExp(r[i], "gi")), "_");
}
console.log(v);

answered Oct 12, 2022 at 12:57

1 Comment

More escapes: const r = ['<', '>', '\)', '\(', '\'', ',', '\\.', ';', '`', '"', '#', '/', '\\\\', '=', '\\+', '\*', '%', '\\$', '\\?', '!', '&', '{', '}', '\[', '\]', '~', '\\^', '\\|', ':'];
0

If you're looking for something quick and easy, try this:

let sr = {'<': '&lt;', '>': '&gt;', '\n': '<br/>'};
let text = '<p>This text \n spans \n multiple\nrows.</p>';
function str_replace(obj, str) {
 Object.entries(obj).forEach((e) => str = str.replaceAll(e[0], e[1]));
 return str;
}
// and run it
console.log(str_replace(sr, text));

Disclaimer: This function uses cumulative replacement and an object for search/replace (evidently)

answered Jun 10, 2024 at 2:32

Comments

-1

One method would be:

var text = $(this).val();
text = text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
$("#output").html(text);
answered Feb 21, 2011 at 18:04

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.