replace() with RegExp on array elements - javascript

I want to write a JavaScript function which converts some simple BBcode Tags like [red] [/red] to Html-Tags. I think the replace() function is the best way to do it. I wrote a simple testfunction to try it, but it does not seem to work.
/**
* #function
* #description Replaces the bb-tags with html-tags
*/
function bbToHtml(form) {
debugger
var text = form.text.value;
bbTags = new Array("[red]", "[yellow]", "[green]", "[/red]", "[/yellow]", "[/green]");
htmlTags = new Array("<font color='red'>", "<font color='yellow'>", "<font color='green'>", "</font>", "<font>", "</font>");
for (var i = 0; i < bbTags.length; i++) {
var re = new RegExp(bbTags[i], "g");
text = text.replace(re, htmlTags[i]);
}
alert(text);
}
It should convert "[red]hello[/red]" to "<font color='red'>hello</font>", but it just gives me a weird string.
What is wrong? I think this has something to do with my regular expression.

[ and ] have special meaning in regular expressions and need to be escaped, moreover you do not need regular expressions the way you've written your code and can just do:
function bbToHtml(form) {
debugger
var text = form.text.value;
bbTags = new Array("[red]", "[yellow]", "[green]", "[/red]", "[/yellow]", "[/green]");
htmlTags = new Array("<font color='red'>", "<font color='yellow'>", "<font color='green'>", "</font>", "<font>", "</font>");
for (var i = 0; i < bbTags.length; i++) {
while(text.indexOf(bbTags[i])!==-1){
text = text.replace(bbTags[i], htmlTags[i]);
}
}
alert(text);
}
Just to let you know, you can use array literals so instead of arrays. new Array(comma seperated values) is identical to [comma seperated values] in javascript.
Also, you can use your array like a map in your case, for example:
var bbTagsToHTML = {}
bbTagsToHtml["[red]"] = "<font color='red'>"
and iterate through that.
If you would like you can escape your regular expressions too, please see How do you use a variable in a regular expression? for a function that does that.
You can also do that manually. "[red]" becomes "\[red\]" (the bracket escaped).

just change this line
text = text.replace(re, htmlTags[i]);
into
text = text.replace(bbTags[i], htmlTags[i]);
removing unuseful code.
replace works also on 'normal' (not regex) values as argument.

If you want to do it with regex you can simplify a lot. No arrays or loops:
var str = '[red]foo[/red] hello world [blue]hey[/blue]',
re = /\[(\w+)\](.*)\[\/\1\]/g;
str = str.replace(re, '<font color="$1">$2</font>');
console.log(str);
//^ <font color="red">foo</font> hello world <font color="blue">hey</font>
Also, as a side note, font is rarely used anymore I'd suggest you use a span with a class.

Related

Javascript RegExp.prototype.test - how to regex values coming from an array

I want to check each values from my array if it matches the string,
however it doesn't work when i'm using console.log(/^reg_arr[i]/.test(str1));
but when I use console.log(/^table/.test(str1)); it works
var str1 = 'table football';
var reg_arr = ["table","football"];
for(var i = 0, reg_arr_length = reg_arr.length; i < reg_arr_length; i++)
{
console.log(/^reg_arr[i]/.test(str1)); /* doesnt work */
}
console.log(/^table/.test(str1)); /* this works */
Is there a problem with my syntax,
Thank you,
Use new RegExp(source: string[, flags: string]) (simply RegExp(source: string[, flags: string]) is also working)
var str1 = 'table football';
var reg_arr = ["table","football"];
for(var i = 0, reg_arr_length = reg_arr.length; i < reg_arr_length; i++)
{
console.log(new RegExp(`^${reg_arr[i]}`).test(str1));
}
Using slashes to define a regular expression doesn't allow you to enter variables into the regular expression, that is, in the following example, str1 is checked to contain "test", not the value of the variable test.
var str1 = "hello";
var str2 = "Hello world";
console.log(/str1/i.test(str2))
To solve this issue, you need to create a new regular expression for each value in the array, something that can be done with new RegExp(str), instead of slashes.
var str1 = "hello";
var str2 = "hello world";
console.log(new RegExp(str1, "i").test(str2))
However, this method has a catch, characters from that string are not escaped. So new RegExp("test.hello") will match "test hello", because the dot is interpreted as a regular expression wildcard character and not a period. To fix that, we first have to manually escape any special characters in our search string (unless the things reg_arr are actually regular expressions). I took the code to do that from the middle of this MDN page.
var str1 = "hello"
var str2 = "hello world"
str1.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
console.log(new RegExp(str, "i").test(str2))
So without changing anything else, your final console.log could look like this:
console.log(new RegExp(reg_arr[i].replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).test(str1));

How to highlight text by using regex

I'm trying writing a script to help highlight when match with regex. Below is my example that what I do now.
var text = "SOMETHING ~WEIRDs~ AND Not WEIRD";
var regexp = /\b(WEIRD)\b/
var matches = text.match(regexp);
for (i = 0; i < matches.length; i++) {
var replace_all = RegExp(matches[i] + "(?![^<]*>|[^<>]*<\/)", "ig");
text = text.replace(eval(replace_all), "<span style='background- color:yellow'>" + matches[i] + "</span>");
}
console.log(text);
The output of the code above is
SOMETHING ~<span style='background- color:yellow'>WEIRD</span>s~ AND Not <span style='background- color:yellow'>WEIRD</span>
The output I want is
SOMETHING ~WEIRDs~ AND Not <span style='background- color:yellow'>WEIRD</span>
I would like to know is that anyway to write a regex contains regex and words provided? Or have any other method can solve this incorrect replace issue.
Your outer regex is fine. The issue is with the inner replace_all regex in the loop , as it replaces all instances of the found string, no matter its position in the original string.
Instead use the original Regex with replace() using the matches within the replacement string, like this:
var text = "SOMETHING ~WEIRDs~ AND Not WEIRD";
var regexp = /\b(WEIRD)\b/
var text = text.replace(regexp, '<span style="background-color: yellow">$1</span>');
console.log(text);
Also, as a general rule, never, ever use eval(). There is always a better solution or alternative.

Javascript string replace() method malfunctioning for dots and commas

I want to replace a text by using the user input values but for the below script dots and commas are malfunctioning when replacing. I tried (/\x/) method but it's not working, maybe because it's a value. So, how can I execute output more accurately?
function myFunction() {
var str = document.getElementById("text").value;
var x = new RegExp(document.getElementById("x").value, "g");
var y = document.getElementById("y").value;
var txt = str.replace(x, y);
document.getElementById("newText").innerHTML = txt;
}
function reset() {
document.getElementById("text").value = "";
}
example:
text = ..........a.a.a..a..a..aaaaaa..a.a.
x = ..a
y = B
output = ........B.BBBBBaaB.a.
but output should be
........B.a.aBBBaaaaaB.a.
(Sorry for the unprofessional example...)
I am just now learning JS and not a professional and I'm trying to make a replacer web page using JS like in MS Notepad where you can press ctrl+H and replace any word or letter.
You're looking for RegExp.escape, unlucky for you - the smart people at the JavaScript technical committee decided to postpone its inclusion in the standard because of an edge case you, or anyone else will likely never run into.
if(!RegExp.escape){
RegExp.escape = function(s){
return String(s).replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
};
}
Then, you can call it on a value and it'll escape it for use in new RegExp:
var raw = document.getElementById("x").value;
var x = new RegExp(RegExp.escape(raw), "g");
You want this regex - [.]{2}[a] or [.][.][a].
Two dots mandatory with trailing a. And it should be of 3 characters.

using multiple .replace calls on an array of variables in Javascript / jQuery

I am working on a tool that would receive text that has been copied from a word document, and return an html output for copy/paste into an email client for email marketing.
During this process, one of the steps the tool needs to handle is the replacement of special characters within the copied values. The output needs to show the encoded values so when they are copied into the email client, they render accordingly during the mail send process
The problem is that there are multiple inputs the user can populate and right now the code is VERY WET... I want to set up the tool to be a little cleaner, and not repeat the code as often.
Currently the input is given to the tool via a prompt();
I am taking that input and replacing the special characters ™, ®, Ø, ´, ”, ‟ and others (partial list given for this example) as needed:
JS (Commented Version)
msg2 = prompt("enter text here");
//long version to tag each replacement with it's identifying name
msg2 = msg2.replace(/[\u0027]/g, '&#39;'); // Apostrophe ´
msg2 = msg2.replace(/[\u2122]/g, '&#153;'); // trademark ™
msg2 = msg2.replace(/[\u00AE]/g, '&#174;'); // R-Ball ®
msg2 = msg2.replace(/[\u201c]/g, '&#34;'); // Left Double Quote ‟
msg2 = msg2.replace(/[\u201D]/g, '&#34;'); // Right Double Quote ”
msg2 = msg2.replace(/[\u2018]/g, '&#39;'); // Left Single Quote ‛
msg2 = msg2.replace(/[\u2019]/g, '&#39;'); // Right Single Quote ’
msg2 = msg2.replace(/[\u2022]/g, '&#2022;') // Bullet •
JS (Short Version)
msg2 = prompt("enter text here");
msg2 = msg2.replace(/[\u0027]/g, '&#39;').replace(/[\u2122]/g,
'&#153;').replace(/[\u00AE]/g, '&#174;').replace(/[\u201c]/g,
'&#34;').replace(/[\u201D]/g, '&#34;').replace(/[\u2018]/g,
'&#39;').replace(/[\u2019]/g, '&#39;').replace(/[\u2022]/g,
'&#2022;');
BUT... I need to run this same replacement on a number of prompts. I don't want to repeat this in the code a bunch of times with each of the variables changing as needed.
What I would rather do is create a function to handle the replacement, and then simply create an array of the variables and run the function on the array...
Example
function txtEncode () {
...replacment code here...
}
var inputTxt = [msg1, msg2, msg3...];
for (var i=0; i < inputTxt.length; i++){
txtEncode(i)
}
Just make an array with replacement pairs:
var replacements = [ ["&", "&"], ["'", """] etc
and apply them one by one:
replacements.forEach(function(pair) {
msg = msg.split(pair[0]).join(pair[1]);
});
split/join is better to replace literal strings than .replace which is intended for use with regular expressions.
Also, your encoding doesn't look right, &#174; will be displayed as ®, not as ®
You can use a global find/replace function and extend the string prototype, I have this code in one of my fiddles, but I can't find the origin.
Code:
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;
};
var msg2 = 'demo \u0027'
var find = ["\u0027"];
var replace = ["&#39;"];
msg2 = msg2.replaceArray(find, replace);
Demo: http://jsfiddle.net/IrvinDominin/YQKwN/
Add a method to the String object for your code.
String.prototype.myCleanString = function(){
return this.replace(/[\u0027]/g, '&#39;')
.replace(/[\u2122]/g,'&#153;')
.replace(/[\u00AE]/g, '&#174;')
.replace(/[\u201c]/g, '&#34;')
.replace(/[\u201D]/g, '&#34;')
.replace(/[\u2018]/g, '&#39;')
.replace(/[\u2019]/g, '&#39;')
.replace(/[\u2022]/g, '&#2022;')
.replace(/foo/g, 'bar');
}
Call as needed... http://jsfiddle.net/XKHNt/

regular expression javascript returning unexpected results

In the below code, I want to validate messageText with first validationPattern and display the corresponding message from the validationPatterns array. Pattern and Message are separated by Pipe "|" character.
for this I am using the below code and always getting wrong result. Can some one look at this and help me?
var messageText = "Message1234";
var validationPatterns = [
['\/^.{6,7}$/|message one'],
['\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b|message two']
];
for (var i = 0; i < validationPatterns.length; i++) {
var validationvalues = validationPatterns[i].toString();
var expr = validationvalues.split("|")[0];
console.log(expr.constructor);
if(expr.test(messageText)) {
console.log("yes");
} else {
console.log("no");
}
}
I know that we cannot use pipe as separator as pipe is also part of regular expression. However I will change that later.
Your validationpatterns are strings. That means:
The backslashes get eaten as they just string-escape the following characters. "\b" is equivalent to "b". You would need to double escape them: "\\b"
You cannot call the test method on them. You would need to construct RegExp objects out of them.
While it's possible to fix this, it would be better if you just used regex literals and separated them from the message as distinct properties of an object (or in an array).
var inputText = "Message1234";
var validationPatterns = [
[/^.{6,7}$/, 'message one'],
[/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/, 'message two']
];
for (var i = 0; i < validationPatterns.length; i++) {
var expr = validationPatterns[i][0],
message = validationPatterns[i][1];
console.log(expr.constructor); // RegExp now, not String
if(expr.test(inputText)) {
console.log(message+": yes");
} else {
console.log(message+": no");
}
}
Your expr variable is still just a string (validationvalues.split("|")[0] will return a string). That's the reason it does not work as a regular expression.
You need to add a line after the initial definition of expr.
expr = new RegExp(expr, 'i');
The 'i' is just an example of how you would use a case-insensitive flag or other flags. Use an empty string if you want a case-sensitive search (the default).
Also, you need to take out the / and / which are surrounding your first pattern. They are only needed when using regular expression literals in JavaScript code, and are not needed when converting strings into regular expressions.

Categories

Resources