JavaScript replace all of linebreaks [duplicate] - javascript

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);
...

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);

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().

text = text.replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '<br/>');

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 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 = {"<" : "<", ">" : ">", "\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 = ["<", ">", "<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)]});
}

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

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'];
const replaceWith = ['<', '>', '<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);

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

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

const items = {
'<': '<',
'>': '>',
'\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)

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 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({">": ">", "<": "<", "\n": "<br/>"});
}
// usage
text = "<span>spam</span>";
htmlspecialchars(text);

jquery have a solution for that.
var htmlString = $( element).html();
$( element ).text( htmlString );
view here:
https://api.jquery.com/html/

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;
}

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);

One method would be:
var text = $(this).val();
text = text.replace(/</g, "<").replace(/>/g, ">");
$("#output").html(text);

Related

Javascript: How to replace all matching strings by html code

Here is my current code:
var filter = ['F', 'p'];
var table_data = ['F1', 'F-BAPP', 'ABC'];
table_data.forEach(function(d)
{
var final_value = addClass(d, filter);
console.log(final_value);
});
function addClass(text, filters)
{
if (filters === '')
{
return text;
}
String.prototype.replaceAll = function(FindText, RepText)
{
regExp = new RegExp(FindText, "gi");
return this.replace(regExp, RepText);
};
filters.forEach(function(kw)
{
text = (text + "").replaceAll(kw, "<span class='_p-filter-matched'>" + kw + "</span>");
});
return text;
}
I want the final_value's output to be like this:
<span class='_p-filter-matched'>F</span>1
<span class='_p-filter-matched'>F</span>-BA<span class='_p-filter-matched'>P</span><span class='_p-filter-matched'>P</span>
But there are two questions:
1. <span> becomes <s<span class='_p-filter-matched'>p</span>an.
2. F-BAPP becomes f-BApp.
So, what should I do? Thank you all.
Your main problem is because you are iterating over the filter array and do a replacement one a time. So when you replace F by "<span class='_p-filter-matched'>" + kw + "</span>" you are adding multiple p characters on the string that the next filter p will going to replace.
On the next approach, I have used the function as second parameter (function(replacement)) of the replace() method to do all the replacements on one shot using also a regular expression that will look for all the filters (example: the regular expression F|p).
Approach:
var filter = ['F', 'p'];
var table_data = ['F1', 'F-BAPP', 'ABC'];
table_data.forEach(function(d)
{
var final_value = addClass(d, filter);
console.log(final_value);
});
function addClass(text, filters)
{
if (!filters.length)
return text;
String.prototype.replaceAll = function(filters, RepText, token)
{
regExp = new RegExp(filters.join("|"), "gi");
return this.replace(regExp, (match) =>
{
return RepText.replace(token, match);
});
};
let repText = "<span class='_p-filter-matched'>*filter*</span>";
let token = "*filter*";
return text.replaceAll(filters, repText, token);
}

Replace last letters in array of strings Javascript

I need to do as follows:
I've got an array of strings containing last names. Some of them ends with letter 'i'.
manLastNames = ["testowski","bucz","idzikowski","gosz"];
I need to make a function which will iterate over this array of strings and if there is an element ending with 'i', I need to replace this 'i' for 'a', otherwise just leave string as it is.
At the end I want to have another array where all last 'i's are replaced with 'a's.
womanLastNames = ["testowska","bucz","idzikowska","gosz"];
This is what I have now, but Im pretty sure that it start being crap at some point
var rep = function() {
var manLastNames = ["testowski","bucz","idzkowski","gosz"];
var womanLastNames = new Array(4);
for (var i=0; i<manLastNames.length; i++) {
var lastName = manLastNames[i];
if (lastName.substr(lastName.length - 1, 1) == 'i') {
lastName = lastName.substr(0, lastName.length - 1) + 'a';
}
}
for (var i=0; i<womanLastNames.length; i++) {
womanLastNames[i] = lastName[i];
}
console.log(womanLastNames);
}
rep();
Try the code:
var manNames = ["testowski","bucz","idzkowski","gosz"];
var womanNames = manNames.map(function(name) {
return name.endsWith("i") ? name.slice(0, -1) + "a" : name;
});
console.log(womanNames)
If your interpreter supports ES6, the following is equivalent:
names.map((name)=>name.endsWith("i") ? name.slice(0, -1) + "a" : name)
Here is solution
var rep = function() {
var manLastNames = ["testowski","bucz","idzkowski","gosz"];
var womanLastNames =[];
for (var i=0; i<manLastNames.length; i++) {
var lastName = manLastNames[i];
if (lastName.charAt(lastName.length - 1) == 'i') {
lastName = lastName.substr(0, lastName.length - 1) + 'a';
}
womanLastNames.push(lastName);
}
console.log(womanLastNames);
}
rep();
Another solution is to use .map method like this, using a callback function:
var manLastNames = ["testowski","bucz","idzikowski","gosz"];
function mapNames(item){
return item[item.length-1]=='i' ? item.substr(0, item.length-1) + "a" : item;
}
console.log(manLastNames.map(mapNames));
Depending on how efficient you need to be, you can use regular expressions to do both tasks:
var new_name = name.replace(/i$/, 'a');
will replace the last "i" in a string with "a" if it exists
var new_name = name.replace(/i/g, 'a');
will replace all "i"s in a string with "a".
var names = ["testowski", "bucz", "idzkowski", "gosz"];
console.log("original", names);
var last_i_replaced = names.map(function(name) {
return name.replace(/i$/, 'a');
});
console.log("last 'i' replaced", last_i_replaced);
var all_i_replaced = names.map(function(name) {
return name.replace(/i/g, 'a');
});
console.log("all 'i's replaced", all_i_replaced);
This should work:
var rep = function() {
var manLastNames = ["testowski","bucz","idzkowski","gosz"];
var womanLastNames = manLastNames;
for(var i=0; i<manLastNames.length;i++){
if(manLastNames[i].charAt(manLastNames[i].length-1)=='i'){
womanLastNames[i]=manLastNames[i].substr(0,womanLastNames[i].length-1)+'a';
}
}
console.log(womanLastNames);
}
rep();
Here is another solution
var manLastNames = ["testowski","bucz","idzkowski","gosz"];
var womanLastNames = []
manLastNames.forEach(x => {
if (x.charAt(x.length-1) === "i") womanLastNames.push(x.slice(0,-1).concat("a"));
else womanLastNames.push(x);
});
console.log(womanLastNames);

How to replace all capture groups if it is generated dynamically?

Consider the following code:
function Matcher(source, search) {
var opts = search.split('');
for (var i = 0; i < opts.length; i++) {
opts[i] = '(' + opts[i] + ')';
}
opts = opts.join('.*');
var regexp = new RegExp(opts, 'gi');
source = source.replace(regexp, function () {
console.log(arguments);
return arguments[1];
});
return source;
}
You call the function passing the source as the first parameter and what you need to match as the second one.
What i need is to replace all capture groups with a bold tag around the coincidence.
As an example, consider the following:
var patt = /m([a-z0-9\-_]*?)r([a-z0-9\-_]*?)i([a-z0-9\-_]*?)e([a-z0-9\-_]*\.[a-z]+)/gi;
var newFileName = fileName.replace(patt, "<strong>m</strong>$1<strong>r</strong>$2<strong>i</strong>$3<strong>e</strong>$4");
This code is an answer from Terry on my previous question but the problem here is that you need to know exactly what you want to replace, and i need it dynamically.
Any thoughts?
It seems like you're creating the pattern the wrong way round. Instead of building a(.*?)b(.*?)c, you create (a).*(b).*(c) - with the capturing groups around the parts you already know. Better:
function wrapEachLetter(source, search, tag) {
var opts = search.split('');
tag = tag || "strong";
return source.replace(new RegExp(opts.join("(.*?)"), 'gi'), function () {
var str = '<'+tag+'>'+opts[0]+'</'+tag+'>';
for (var i=1; i<opts.length; i++)
str += arguments[i] + '<'+tag+'>'+opts[i]+'</'+tag+'>';
return str;
});
}
Example:
> wrapEachLetter("testExampleString", "tex", "b")
"<b>t<b><b>e<b>stE<b>x<b>ampleString"
Capture the delimiters too and then process only even subgroups, leaving odd ones as is:
s = "ABC---DEF---HIJ"
re = /(\w+)(.*?)(\w+)(.*?)(\w+)/
s.replace(re, function() {
return [].slice.call(arguments, 1, -2).map(function(a, n) {
return n & 1 ? a : "<strong>" + a + "</strong>"
}).join("")
})
> "<strong>ABC</strong>---<strong>DEF</strong>---<strong>HIJ</strong>"
However, if your goal is to highlight only individual characters, it's much simpler this way:
str = "myfile.js"
letters = "mis"
re = new RegExp("[" + letters + "]", "gi")
str.replace(re, "<b>$&</b>")
> "<b>m</b>yf<b>i</b>le.j<b>s</b>"
or, without regular expressions:
str = "myfile.js"
letters = "mis"
str.split("").map(function(s) {
return letters.indexOf(s) >= 0 ? "<b>" + s + "</b>" : s
}).join("")
> "<b>m</b>yf<b>i</b>le.j<b>s</b>"
var input = "aBcDeFgHiJk",
match = 'be';
str = '',
reg = '',
i = 0;
function escapeRegExp(c) {
return c.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
// /(.*)(b)(.*)(e)(.*)/gi
// '$1<b>$2</b>$3<b>$4</b>$5'
for (var c in match) {
if (i == 0) {
str += '$' + ++i;
reg += '(.*)';
i++;
}
str += '<b>$' + i++ + '</b>$' + i++;
reg += '(' + escapeRegExp(match[c]) + ')(.*)';
}
alert(input.replace(new RegExp(reg, 'ig'), str)); // <- a<b>B</b>cD<b>e</b>FgHiJk

String modification issue in JS

I have a string like "word_count". How can I transform it to "WordCount" in an elegant way using JavaScript? My decision seems too complicated to me. I'll be very grateful for your help.
function titleCase(str)
{
return str.split("_")
.map(function (s) { return s.charAt(0).toUpperCase() + s.slice(1); })
.join("");
}
Take a look at this. I don't want to just copy paste everything here, but it seems to be just what you're looking for.
Here is the function modified to fit your request:
String.prototype.toCamel = function(){
return this.replace(/((^|\_)[a-z])/g, function($1){
return $1.toUpperCase().replace('_','');});
};
And here it is in action.
You can use a regular expression to match either a letter at the start of the string or a letter after an underscore, and use a callback to turn the letter into uppercase:
s = s.replace(/(?:^|_)([a-z])/g, function(m, g){
return g.toUpperCase();
});
Demo: http://jsfiddle.net/Guffa/ByU6P/
Simple, like this:
var string = "word_count".split("_");
for(var i = 0; i<string.length;i++) {
string[i] = string[i].charAt(0).toUpperCase() + string[i].substr(1);
}
var myNiceString = string.join();
If you want to add it to the String object, you can do this:
String.prototype.titleCase = function() {
var split = this.split("_");
for(var i = 0; i<split.length;i++) {
split[i] = split[i].charAt(0).toUpperCase() + split[i].substr(1);
}
return split.join("");
}
You'd call it like "word_count".titleCase();
You can use a function like the following:
var Pascalize = function(word) {
var x = word;
result = '';
if(-1 != word.indexOf('_')) {
x = word.split('_');
for(var i=0;i<x.length;i++) {
result += x[i].substr(0, 1).toUpperCase() + x[i].substr(1);
}
}
if('' == result) { result = word; }
return result;
};
var PascalCaseString = Pascalize("this_is_a_test");
// PascalCaseString value is now 'ThisIsATest'
Here's a working example
var str = "word_count";
var re = /\b(.)([^_]+)_(.)/;
var newWord = str.replace(re, function(m,f,t,l){ return f.toUpperCase() + t + l.toUpperCase();})
console.log(newWord);
Using jQuery, you could do the following:
var result = '';
$.each('word_count'.split('_'), function(idx,elem){
result = result + elem.substr(0,1).toUpperCase() + elem.substr(1);
});
New version (works with any amount of _):
function fixString(sString) {
var aWords = sString.split("_"),
sResults = "";
for (var i in aWords)
sResults += aWords[i].charAt(0).toUpperCase() + aWords[i].slice(1);
return sResults;
}
The compressed form:
function fixString(c){var d=c.split("_"),a="";for(var b in d){a+=d[b].charAt(0).toUpperCase()+d[b].slice(1)}return a};
Old:
function fixString(sString) {
return sString.replace(/(.*)_(.*)/, function(sWhole, $1, $2, sWTF) {
return ucfirst($1) + ucfirst($2);
} )
function ucfirst (str) {
str += '';
var f = str.charAt(0).toUpperCase();
return f + str.substr(1);
}
}
... or the compressed version:
function fixString(b){return b.replace(/(.*)_(.*)/,function(e,c,f,d){return a(c)+a(f)});function a(d){d+="";var c=d.charAt(0).toUpperCase();return c+d.substr(1)}};
Of course, this is used like fixString("word_count") which results in your desired WordCount.
I've looked at all the answer and none did precisely what I wanted. I wanted an idempotent function which converted to camelCase (not PascalCase) and I liked the String prototype extension approach (although obviously this isn't always the best medicine).
Anyway, here's where I ended up:
String.prototype.camelize = function(){
var pascalCase = this.replace(/((^|\_)[a-z])/g, function($1){
return $1.toUpperCase().replace('_','');
});
return pascalCase.charAt(0).toLowerCase() + this.slice(1);
};
var aStringLike = "word_count";
// magic follows
aStringLike = "WordCount";

Replace multiple strings at once

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);
...
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);
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().
text = text.replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '<br/>');
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 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 = {"<" : "<", ">" : ">", "\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 = ["<", ">", "<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)]});
}
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
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'];
const replaceWith = ['<', '>', '<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);
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
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
const items = {
'<': '<',
'>': '>',
'\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)
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 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({">": ">", "<": "<", "\n": "<br/>"});
}
// usage
text = "<span>spam</span>";
htmlspecialchars(text);
jquery have a solution for that.
var htmlString = $( element).html();
$( element ).text( htmlString );
view here:
https://api.jquery.com/html/
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;
}
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);
One method would be:
var text = $(this).val();
text = text.replace(/</g, "<").replace(/>/g, ">");
$("#output").html(text);

Categories

Resources