Js replace and Regex exclude a word - javascript

I have this issue with regex, it doesn't really have friendly syntax for me :(.
Basically I need to match some text and wrap the matched word/letter with a <strong>.
html = html.replace(new RegExp('(' + word + ')', 'ig'), function ($1, match) {
return '<strong>' + match + '</strong>';
Now everything works fine except that in some occasion, the previously added <strong> get matched to messing up the html.
So I basically need the html.replace function to ignore any <strong> word during the matching.
I have tried to change new RegExp('(' + word + ')' with new RegExp('(?!\<strong\>)(' + word + ')' but I still have issue.
Ex.
'<strong>Alpinestars</strong> SMX Plus Gore-Tex Boots'.replace(new RegExp('(o)(?!</strong>)', 'ig'), function ($1, match) {
return '<strong>' + match + '</strong>';});
returns
"<str<strong>o</strong>ng>Alpinestars</str<strong>o</strong>ng> SMX Plus G<strong>o</strong>re-Tex B<strong>o</strong><strong>o</strong>ts"

You can check if you are not inside an element node with (?![^>]*>) look-ahead:
function escapeRegExp(string){
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
var key = 'o';
var s = '<strong>Alpinestars</strong> SMX Plus Gore-Tex Boots';
var res = s.replace(RegExp(escapeRegExp(key) + '(?![^>]*>)', 'ig'), function (m) {
return '<strong>' + m + '</strong>';});
document.getElementById("t").innerHTML = res.replace(/>/g, ">").replace(/</g, "<");
<div id="t"/>
You also do not need any capturing groups (unless you are using alternations like boots|caps|hats) and do not have to use new with RegExp. I also added an escapeRegExp function from MDN to escape special characters in key if any.

You were close. You just had the order wrong. According to the following mdn page, the x(?!y) means: Matches x only if x is not followed by y.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
So, this seems to work for me:
var word = 'and';
'dogs <strong>and</strong> cats <strong>and</strong>'.replace(
new RegExp('(' + word + ')(?!</strong>)', 'ig'),
function ($1, match) {
return '<strong>' + match + '</strong>';
}
);

Related

RegEx Data Values Javascript white Space

I am trying to add the correct white space for data i am receiving. currently it shows like this
NotStarted
ReadyforPPPDReview
this is the code i am using
.replace(/([A-Z])/g, '$1')
"NotStarted" shows correct "Not Started" but "ReadyforPPPDReview" shows "Readyfor P P P D Review" when it should look like this "Ready for PPPD Review"
what is the best way to handle both of these using one regex or function?
You would need an NLP engine to handle this properly. Here are two approaches with simple regex, both have limitations:
1. Use list of stop words
We blindly add spaces before and after the stop words:
var str = 'NotStarted, ReadyforPPPDReview';
var wordList = 'and, for, in, on, not, review, the'; // stop words
var wordListRe = new RegExp('(' + wordList.replace(/, */g, '|') + ')', 'gi');
var result1 = str
.replace(wordListRe, ' $1 ') // add space before and after stop words
.replace(/([a-z])([A-Z])/g, '$1 $2') // add space between lower case and upper case chars
.replace(/ +/g, ' ') // remove excessive spaces
.trim(); // remove spaces at start and end
console.log('str: ' + str);
console.log('result1: ' + result1);
As you can imagine the stop words approach has some severe limitations. For example, words formula input would result in for mula in put.
1. Use a mapping table
The mapping table lists words that need to be spaced out (no drugs involved), as in this code snippet:
var str = 'NotStarted, ReadyforPPPDReview';
var spaceWordMap = {
NotStarted: 'Not Started',
Readyfor: 'Ready for',
PPPDReview: 'PPPD Review'
// add more as needed
};
var spaceWordMapRe = new RegExp('(' + Object.keys(spaceWordMap).join('|') + ')', 'gi');
var result2 = str
.replace(spaceWordMapRe, function(m, p1) { // m: matched snippet, p1: first group
return spaceWordMap[p1] // replace key in spaceWordMap with its value
})
.replace(/([a-z])([A-Z])/g, '$1 $2') // add space between lower case and upper case chars
.replace(/ +/g, ' ') // remove excessive spaces
.trim(); // remove spaces at start and end
console.log('str: ' + str);
console.log('result2: ' + result2);
This approach is suitable if you have a deterministic list of words as input.

jQuery Replace Second Space of Sentence

I want to replace second space occurrence of the sentence with a br.
I have tried this but it is deleting the rest.
var title = "My Title Needs Brace".split(" ").slice(0, 2).join(" ");
That will do the trick:
"My Title Needs Brace"
.split(' ')
.reduce(function (str, part, i) {
return str + (i === 2 ? '<br/>' : ' ') + part
});
// "My Title<br/>Needs Brace"
Let's break it and see how it works:
First, we take the string and split it. we'll use " " as our separator
"My Title Needs Brace".split(' ')
// ["My", "Title", "Needs", "Brace"]
Second, we'll use reduce to combine the array back into one string
["My", "Title", "Needs", "Brace"]
.reduce(function (str, part) { return str + ' ' + part }, '');
// "My Title Needs Brace"
Why reduce and not join?
The advantage of reduce over join is that it allows us to use a function, which will give us a fine-grained control over how we join back each part of the string
Now, all that left is to replace the 2nd space with <br/>,
for that, we'll use the 3rd argument of the reduce function, which stands for the index, and ask:
is this the 3rd part? use <br/>
otherwise, use " "
"My Title Needs Brace"
.split(' ')
.reduce(function (str, part, i) {
return str + (i === 2 ? '<br/>' : ' ') + part
});
// "My Title<br/>Needs Brace"
Note that this is the index of the string "part", not the spaces between them so the index is 2, not 1.
More about:
split
reduce
join
Try the following:
var title = "My Title Needs Brace".split(" ");
title.forEach(function(item, i, title){
if(i==1)
title[i] += "<br/>";
else
title[i] += ' ';
})
console.log(title.join(''));
I want to replace second space occurrence of the sentence with a br.
The simple way to do that is to add "<br/>" to the second element.
Here is the Code.
$(document).ready(function(){
var title = "My Title Needs Brace".split(" ");
title[1] = title[1]+"<br/>";
var newstr = title.join(" ");
$("#textd").html(newstr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="textd">
</div>
maybe that will help :
var title = "My Title Needs Brace".split(" ");
t1=title [0]; My
t2=title[1]; // Title
t3=title[2]; // Needs
t4=title[3]; // Brace
you can drew here anything :
var htmlString = '' + t1 +''+ t2 + '<br />' + t3 +''+ t4 + '';
$('Anywhere').append(htmlString);
You can do this without splitting the string:
var title = 'My Title Needs Brace'.replace(/( .*?) /, '$1<br>');
Here, String.replace takes a RegExp and a string as arguments. The regex matches everything from the first space up through the second space, keeping everything except the second space in a capturing group. The string replaces the entire match with the contents of the capturing group, followed by '<br>'. Since the capturing group doesn't include the second space, this effectively only replaces the second space.

Replacing using regex in a string javascript

I am trying to replace a particular string using regex.
var replace = {'<RAndom>': "random object"};
I am replacing it using the dynamic regex because i have a lot of objects.
var tagsText = "<RAndom> hellow world";
var regex = new RegExp('\\b(' + Object.keys(replace).join('|') + ')\\b', 'g');
tagsText = tagsText.replace(regex, function(match) {
return replace[match] + match;
});
But it is not working.I think the problem is with the semicolon but i am not sure.The output is again the same.
"<RAndom> hellow world"
Any ideas?
Problem is presence of \b (word boundary) on each side that is placed before & and ;. Both & and ; are not non-word characters and \b cannot be asserted before and after non-word chars.
You can use \B instead:
var regex = new RegExp('\\B(' + Object.keys(replace).join('|') + ')\\B', 'g');
and then
tagsText = tagsText.replace(regex, function(match) {
return replace[match] + match;
});
//=> "random object<RAndom> hellow world"
The word boundary \b and non-word boundary assertion behavior depends on the context. Make it context-independent with unambiguous (^|\W) and ($|\W):
var replace = {'<RAndom>': "random object"};
var tagsText = "<RAndom> hellow world";
var regex = new RegExp('(^|\\W)(' + Object.keys(replace).join('|') + ')(\\W|$)', 'g');
tagsText = tagsText.replace(regex, function(match, g1, g2, g3) {
return replace[g2] ? replace[g2] + match : match;
});
// And just a demo below
document.body.innerHTML = "<pre>" + tagsText.replace(/&/g, '&') + "</pre>";
The (^|\W) will match the start of string or a non-word character. The ($|\W) will match the end of the string or a non-word character.
Since we have 3 groups now, we can pass them as arguments to the replace callback. With replace[g2] ? replace[g2] + match : match;, we first check if there is a value for g2 key, and if yes, perform the replacement. Else, just return the match.

regular expression :inserting * make it computable

I have a regular expression as
ysin(yx)
i need to insert * as y*sin(y*x)
suppose my equation is yxsin(y) i need to get output as y*x*sin(y)
i tried with this code
function addStars(str) {
return str.replace(/(\))([A-Za-z])/g,function(str, gr1, gr2) { return gr1 + "*" + gr2 }).replace(/x([A-Za-wy-z])/g,function(str, gr1) { return "x*" + gr1 });
}
var t=addStars("ysin(yx)");
alert(t);
what is wrong with this code.
I suggest using regular back-references in this case since you are not analyzing or manipulating the capture groups. The problem is that you are trying to match some letter after a ) with /(\))([A-Za-z])/g - and you do not have any text after ) in your example string ysin(yx).
Here is a possible fix where I combined the x and y into a character class and set a capture group to be able to restore them in the result:
function addStars(str) {
return str.replace(/([xy])([A-Za-xz])/g,"$1*$2");
// | | ^
// ----------------------|
}
var t=addStars("ysin(yx)");
document.write(t + "<br/>");
var t=addStars("yxsin(y)");
document.write(t);
I've generalized the approch using a function list as an anchor and splitting the variables list. The regex is case insensitive and accepts any letter [a-z] as variables prior and as arguments of the function. The trigonometric function list is (asin|acos|atan|sin|cos|tan) (can be expanded as well, only remember to put the longest function names first!).
Check if can be useful:
function addStars(str) {
return str.replace(/([a-z]*?)(asin|acos|atan|sin|cos|tan)\(([^\)]*)\)/i, function(str, vars, funcName, args) {
return vars.split('').join('*') + '*' + funcName + '(' + args.split('').join('*')+')';});
}
var t=addStars("ysin(yx)");
document.write(t + "<br/>");
var t=addStars("yxsin(y)");
document.write(t + "<br/>");
var t=addStars("ycos(abyxz)");
document.write(t + "<br/>");
var t=addStars("yxatan(yxz)");
document.write(t + "<br/>");

issue with replace() method in javascript when replacing spaces

This is the function I am working with:
function replaceH1s() {
$("h1").each(function(){
h1name = $(this).text();
stuff = h1name.toLowerCase().replace(' ','-');
$(this).html('<img src="/assets/image/h1_' + stuff + '.png" alt="' + h1name + '" />');
})
}
I can't figure out for the life of me why this function replaces the first space in h1name string with a hyphen, but not any of the subsequent ones. I tried unescaping and escaping (and then replacing %20 it stumbles upon with hyphens, but that did the same thing). I tried regular expressions for catchall whitespace and that did the same thing. I feel like I am not seeing something super fundamental here.
You need to specify a global regular expression. Otherwise it only matches the first occurrence.
// regular expression
function replaceH1s() {
$("h1").each(function(){
h1name = $(this).text();
stuff = h1name.toLowerCase().replace(/\s+/g, '-'); // matches all whitespace
// use / /g to match a single space
$(this).html('<img src="/assets/image/h1_' + stuff + '.png" alt="' + h1name + '" />');
})
}
// firefox only
function replaceH1s() {
$("h1").each(function(){
h1name = $(this).text();
stuff = h1name.toLowerCase().replace(' ', '-', 'g');
$(this).html('<img src="/assets/image/h1_' + stuff + '.png" alt="' + h1name + '" />');
})
}
stuff = h1name.toLowerCase().replace(/ /g, '-');
The replace function was designed to only replace the first instance of the string you are searching for. If you want to replace all instances, then using regular expressions would work better.
take a look at this page for more information.
If you were trying to replace all spaces with - your close but not quite there
The replace function in JavaScript only replaces the first value it finds that matches and quits. Here is a replaceAll function.
stuff = h1name.toLowerCase().replace(' ' + /g, '-');​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
alert(stuff); //make sure this is what you want
the /g specifies replace all.

Categories

Resources