Replace first occurrence with one value and second with another - javascript

Giving this original string...
Test text _with bold_ and perhaps one another text _with bold in the same string_.
... how to efficiently replace the first occurrence of " _ " with "< b >" and the second occurrence " _ " with "< /b >" to achieve the following result:
Test text <b>with bold</b> and perhaps one more text <b>with bold in the same string</b>.
Note: I have an array of hundreds of those strings that will need to go through this process in order to render in the page.

You can use regex for this.
The replace-pattern is the following:
_(.*?)_ with the flag g at the end - so it will replace until all occurances are satisfied.
The ? in the regex says it will stop matching at the first _ afert the opening _ (non-greedy).
<b>$1</b> says replace the matched string with this. Where the $1 refers to the content matched in the brackets ()
var text = "This is _bold text_ and here _some more_";
var text_replaced = text.replace(/_(.*?)_/g, '<b>$1</b>');
document.getElementById('result').innerHTML = text_replaced;
<span id="result" />

You can run a while loop which checks if there any more underscores in the text and replaces them, assuming that there must be an even number of "_" in the text:
var test = "text _with bold_ and perhaps one another text _with bold in the same string_.";
b_index = test.indexOf("_");
while (b_index != -1) {
test = test.replace("_", "<b>");
test = test.replace("_", "</b>");
b_index = test.indexOf("_");
}
After the while loop, you can assign the innerHTML of whichever element you wish to the variable test.

Related

Find first word in a string after a . in javascript

I am working on a school assignment where we have to highlight the first word after a "." in a text with the press on a button.
As far as i've come I have created a HTML page, the HTML page contains a button and on click it is supposed to highligt the first word after a "." I have discovered that I probably have to use split and or slice.
function highligtWord(){
var tekst = document.getElementById("tekst").innerHTML;
for (var i = 0 ; i < tekst.length; i++) {
var arr = tekst.split(". ")[i].split(" ")[0]
console.log(arr)
var res = tekst.replace(`${arr}`, "<span style=background-color:yellow>" + `${arr}` + "</span>" );
document.getElementById("tekst").innerHTML += res;
}
So far this does not work as intended as it "highlight" words that aren't after a "." so my question is, what do i do wrong?
And how can I get you "highligt" all words after a "." instead?
Thanks in advance
It'd probably be easier to use a regular expression - match \. (a literal dot), then match \S+ - one or more non-space characters. Then replace with the non-space characters surrounded by the highlight span:
const elm = document.getElementById("tekst");
elm.innerHTML = elm.innerHTML.replace(
/(\. *)(\S+)/,
'$1<span style=background-color:yellow>$2</span>'
);
<div id="tekst">foo bar. baz should be highlighted.</div>
If you want to highlight all words that follow a ., use the global flag instead for the regular expression (use /g).

Replace a specific character from a string with HTML tags

Having a text input, if there is a specific character it must convert it to a tag. For example, the special character is *, the text between 2 special characters must appear in italic.
For example:
This is *my* wonderful *text*
must be converted to:
This is <i>my</i> wonderful <i>text</i>
So I've tried like:
const arr = "This is *my* wonderful *text*";
if (arr.includes('*')) {
arr[index] = arr.replace('*', '<i>');
}
it is replacing the star character with <i> but doesn't work if there are more special characters.
Any ideas?
You can simply create wrapper and thereafter use regular expression to detect if there is any word that is surrounded by * and simply replace it with any tag, in your example is <i> tag so just see the following
Example
let str = "This is *my* wonderful *text*";
let regex = /(?<=\*)(.*?)(?=\*)/;
while (str.includes('*')) {
let matched = regex.exec(str);
let wrap = "<i>" + matched[1] + "</i>";
str = str.replace(`*${matched[1]}*`, wrap);
}
console.log(str);
here you go my friend:
var arr = "This is *my* wonderful *text*";
const matched = arr.match(/\*(?:.*?)\*/g);
for (let i = 0; i < matched.length; i++) {
arr = arr.replace(matched[i], `<i>${matched[i].replaceAll("*", "")}</i>`);
}
console.log(arr);
an explanation first of all we're matching the regex globaly by setting /g NOTE: that match with global flag returns an array.
secondly we're looking for any character that lies between two astrisks and we're escaping them because both are meta characters.
.*? match everything in greedy way so we don't get something like this my*.
?: for non capturing groups, then we're replacing every element we've matched with itself but without astrisk.

regex replace first element

I have the need to replace a HTML string's contents from one <br> to two. But what I can't achieve is when I have one tag following another one:
(<br\s*\/?>)
will match all the tags in this text:
var text = 'text<BR><BR>text text<BR>text;'
will match and with the replace I will have
text = text.replace.replace(/(<br\s*\/?>)>/gi, "<BR\/><BR\/>")
console.log(text); //text<BR/><BR/><BR/><BR/>text text<BR/><BR/>text;"
Is there a way to only increment one tag with the regex? And achieve this:
console.log(text); //text<BR/><BR/><BR/>text text<BR/><BR/>text;"
Or I only will achieve this with a loop?
You may use either
var text = 'text<BR><BR>text text<BR>text;'
text = text.replace(/(<br\s*\/?>)+/gi, "$&$1");
console.log(text); // => text<BR><BR><BR>text text<BR><BR>text;
Here, (<br\s*\/?>)+/gi matches 1 or more sequences of <br>s in a case insensitive way while capturing each tag on its way (keeping the last value in the group beffer after the last it, and "$&$1" will replace with the whole match ($&) and will add the last <br> with $1.
Or
var text = 'text<BR><BR>text text<BR>text;'
text = text.replace(/(?:<br\s*\/?>)+/gi, function ($0) {
return $0.replace(/<br\s*\/?>/gi, "<BR/>") + "<BR/>";
})
console.log(text); // => text<BR/><BR/><BR/>text text<BR/><BR/>text;
Here, the (?:<br\s*\/?>)+ will also match 1 or more <br>s but without capturing each occurrence, and inside the callback, all <br>s will get normalized as <BR/> and a <BR/> will get appended to the result.
You can use negative look ahead (<br\s*\/?>)(?!<br\s*\/?>)/ to increment only the last tag if there are any consecutive:
var text = 'text<BR><BR>text text<BR>text;'
text = text.replace(/(<br\s*\/?>)(?!<br\s*\/?>)/gi, "<BR\/><BR\/>")
console.log(text);

JavaScript Replace Text with HTML Between it

I want to replace some text in a webpage, only the text, but when I replace via the document.body.innerHTML I could get stuck, like so:
HTML:
<p>test test </p>
<p>test2 test2</p>
<p>test3 test3</p>
Js:
var param = "test test test2 test2 test3";
var text = document.body.innerHTML;
document.body.innerHTML = text.replace(param, '*' + param + '*');
I would like to get:
*test test
test2 test2
test3* test3
HTML of 'desired' outcome:
<p>*test test </p>
<p>test2 test2</p>
<p>test3* test3</p>
So If I want to do that with the parameter above ("test test test2 test2 test3") the <p></p> would not be taken into account - resulting into the else section.
How can I replace the text with no "consideration" to the html markup that could be between it?
Thanks in advance.
Edit (for #Sonesh Dabhi):
Basically I need to replace text in a webpage, but when I scan the
webpage with the html in it the replace won't work, I need to scan and
replace based on text only
Edit 2:
'Raw' JavaScript Please (no jQuery)
This will do what you want, it builds a regex expression to find the text between tags and replace in there. Give it a shot.
http://jsfiddle.net/WZYG9/5/
The magic is
(\s*(?:<\/?\w+>)*\s*)*
Which, in the code below has double backslashes to escape them within the string.
The regex itself looks for any number of white space characters (\s). The inner group (?:</?\w+>)* matches any number of start or end tags. ?: tells java script to not count the group in the replacement string, and not remember the matches it finds. < is a literal less than character. The forward slash (which begins an end html tag) needs to be escaped, and the question mark means 0 or 1 occurrence. This is proceeded by any number of white space characters.
Every space within the "text to search" get replaced with this regular expression, allowing it to match any amount of white space and tags between the words in the text, and remember them in the numbered variables $1, $2, etc. The replacement string gets built to put those remembered variables back in.
Which matches any number of tags and whitespace between them.
function wrapTextIn(text, character) {
if (!character) character = "*"; // default to asterik
// trim the text
text = text.replace(/(^\s+)|(\s+$)/g, "");
//split into words
var words = text.split(" ");
// return if there are no words
if (words.length == 0)
return;
// build the regex
var regex = new RegExp(text.replace(/\s+/g, "(\\s*(?:<\\/?\\w+>)*\\s*)*"), "g");
//start with wrapping character
var replace = character;
//for each word, put it and the matching "tags" in the replacement string
for (var i = 0; i < words.length; i++) {
replace += words[i];
if (i != words.length - 1 & words.length > 1)
replace += "$" + (i + 1);
}
// end with the wrapping character
replace += character;
// replace the html
document.body.innerHTML = document.body.innerHTML.replace(regex, replace);
}
WORKING DEMO
USE THAT FUNCTION TO GET TEXT.. no jquery required
First remove tags. i.e You can try document.body.textContent / document.body.innerText or use this example
var StrippedString = OriginalString.replace(/(<([^>]+)>)/ig,"");
Find and replace (for all to be replace add 1 more thing "/g" after search)
String.prototype.trim=function(){return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');};
var param = "test test test2 test2 test3";
var text = (document.body.textContent || document.body.innerText).trim();
var replaced = text.search(param) >= 0;
if(replaced) {
var re = new RegExp(param, 'g');
document.body.innerHTML = text.replace(re , '*' + param + '*');
} else {
//param was not replaced
//What to do here?
}
See here
Note: Using striping you will lose the tags.

Find a string after a special character, move it and wrap a div around it

I have this HTML code, for example:
<div class="new">
<div class="in"></div>
<label>some text now watch this | the-thing</label>
</div>
I want to:
find the text thats after the "|" character
move it outside the label
wrap a span tag around it
I know how to do the 2nd and 3rd part, but I don't understand how to manipulate the string to begin with.
Here's a working example: http://jsfiddle.net/jfriend00/TaDKp/.
var re = /\|\s*(.*)$/;
var o = $(".new label");
var match = o.text().match(re);
if (match) {
o.text(o.text().replace(re, ""));
o.after("<span class='special'>" + match[1] + "</span>");
}
The steps described:
Find the desired label object
Find the text in the text of the label object using a regular expression
If the text is found, remove it from the label
Insert a span with that text after the label
You can use a regular expression to get/replace the text. Then create a span element and append it after the label.
var str = $( "div.new label" ).html();
var match = str.match( /\|(.*)/ )[1];
$( "div.new label" ).html( str.replace( /\|(.*)/, "" ) );
$( "div.new" ).append( "<span>" + match + "</span>" );
Example: http://jsfiddle.net/4m9AX/
You could use JavaScript regular expressions to capture and replace the text after the special character. Read about the standard RegExp class.
To do the first part you need to access the content of the label. Do that using jQuery. Something like:
$(".new > label").val();
And then to get the text after the "|" character, what you need is two javascript functions: indexOf and substr.
You'll need to use indexOf() to find the text after the character
var str = $('.new label').text();
var strToMove = str.substring(str.indexOf('|') + 1);
I don't have time to write the code, but here is probably how you should go about it:
1: Add an id to the label e.g. <label id="originaltext">
2. In your javascript, assign a variable to: document.getElementById("originaltext").innerText;
3. Use string.split to split the text using the '|' character into 2 variables
4. Set the contents of the original div to the text before the pipe using: document.getElementById("originaltext").innerText = stringbeforepipe
5. Set the contents of the new div using the same method except using the variable storing the string after the seperator.
So you want the final html snippet to be
<div class="new">
<div class="in"></div>
<span>the-thing</span>
<label>some text now watch this</label>
</div>
?
The jquery would look something like this:
var node = $('label').contains('|').
var txt = node.val();
var newtxt = txt.substr(0, txt.indexOf('|')-1);
var cuttxt = txt.substr(txt.indexOf('|')+);
node.before('<span>'' + cuttxt + '</span>');
node.text(newtxt);
Not test, probably won't work, YMMV, etc...
You can get the string thus:
var str = $('div.new label').text();
Then use string primitives to slice the bit of the string you want.

Categories

Resources