Is there an easy equivalent to this in JavaScript?
$find = array("<", ">", "\n");
$replace = array("<", ">", "<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);
...
This question is related to
javascript
jquery
replace
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 = ["<", ">", "<br/>"];
textarea = textarea.replaceArray(find, replace);
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) {_x000D_
for (var i = 0; i < find.length; i++)_x000D_
str = str.replace(new RegExp(find[i],"g"), replace[i]);_x000D_
return str;_x000D_
};_x000D_
_x000D_
// Fails in some cases:_x000D_
console.log( replaceCumulative( "tar pit", ['tar','pit'], ['capitol','house'] ) );_x000D_
console.log( replaceCumulative( "you & me", ['you','me'], ['me','you'] ) );
_x000D_
function replaceBulk( str, findArray, replaceArray ){_x000D_
var i, regex = [], map = {}; _x000D_
for( i=0; i<findArray.length; i++ ){ _x000D_
regex.push( findArray[i].replace(/([-[\]{}()*+?.\\^$|#,])/g,'\\$1') );_x000D_
map[findArray[i]] = replaceArray[i]; _x000D_
}_x000D_
regex = regex.join('|');_x000D_
str = str.replace( new RegExp( regex, 'g' ), function(matched){_x000D_
return map[matched];_x000D_
});_x000D_
return str;_x000D_
}_x000D_
_x000D_
// Test:_x000D_
console.log( replaceBulk( "tar pit", ['tar','pit'], ['capitol','house'] ) );_x000D_
console.log( replaceBulk( "you & me", ['you','me'], ['me','you'] ) );
_x000D_
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()
.
text = text.replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '<br/>');
You could use the replace method of the String
object with a function in the second parameter:
First Method (using a find and replace Object)
var findreplace = {"<" : "<", ">" : ">", "\n" : "<br/>"};
textarea = textarea.replace(new RegExp("(" + Object.keys(findreplace).map(function(i){return i.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")}).join("|") + ")", "g"), function(s){ return findreplace[s]});
Second method (using two arrays, find and replace)
var find = ["<", ">", "\n"];
var replace = ["<", ">", "<br/>"];
textarea = textarea.replace(new RegExp("(" + find.map(function(i){return i.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")}).join("|") + ")", "g"), function(s){ return replace[find.indexOf(s)]});
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)]});
}
A more visual approach:
String.prototype.htmlProtect = function() {
var replace_map;
replace_map = {
'\n': '<br />',
'<': '<',
'>': '>'
};
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();
// <b>tell me a story, <br /><i>bro'</i>
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.
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
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 = ["<", ">", "<br/>"];
In this case, no imperative programming is going on.
Using ES6:
There are many ways to search
for strings and replace
in JavaScript
. One of them is as follow
const findFor = ['<', '>', '\n'];_x000D_
_x000D_
const replaceWith = ['<', '>', '<br/>'];_x000D_
_x000D_
const originalString = '<strong>Hello World</strong> \n Let\'s code';_x000D_
_x000D_
let modifiedString = originalString;_x000D_
_x000D_
findFor.forEach( (tag, i) => modifiedString = modifiedString.replace(new RegExp(tag, "g"), replaceWith[i]) )_x000D_
_x000D_
console.log('Original String: ', originalString);_x000D_
console.log('Modified String: ', modifiedString);
_x000D_
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("<", "<");
s = s.replace(">", ">");
s = s.replace("\n", "<br/>");
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);
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
One method would be:
var text = $(this).val();
text = text.replace(/</g, "<").replace(/>/g, ">");
$("#output").html(text);
Source: Stackoverflow.com