Reputation: 62
I am trying to figure out how to manipulate string like this:
string abc = "<p> Hello world <em> How are you? </em> abc <em> You there </em> </p>"
into
string def = "<p> Hello world </> <em> How are you? </> <p> abc </> <em> You there </>"
Explanation: For every tag the closing tag will be </>
this and I am not allowed to use nested tags as we do in normal HTML. That's why my string def
has </>
after every opening tag.
<p> hello world </> (tag closed) <em> how are you? </> (em tag closed) <p> abc </> (p tag closed) <em> You there </> (em tag closed)
I tried using exec on regex to find HTML closing tags and replace them with </>. It worked but unfortunately, I couldn't figure out how to work with opening tags.
I also tried splitting a string using space ' ' and looping through the array. But no luck.
Can anyone please guide me through this?
Upvotes: -1
Views: 102
Reputation: 3707
Using regex in this case would be quite difficult, we can split the the array over " "
and simply loop over it and decide the current state of the string and tags.
function changeHTMLEndTags(html_string = "") {
// adding a space before '<' and after '>'
html_string = html_string.replace(/(<)/g, ' <').replace(/(>)/g, '> ');
// removing multiple spaces introduced due to above operation
// and triming the start and end of the string
html_string = html_string.replace(/\s\s+/g, ' ').trim();
html_string_words = html_string.split(" ");
final_html_string = "";
last_opening_tag = null;
for(i = 0; i < html_string_words.length; ++i) {
current_word = html_string_words[i];
// if the current_word is an opening tag
if (current_word.match(/<\w+>/)) {
if (last_opening_tag === null) {
final_html_string += current_word + " ";
last_opening_tag = current_word;
}
else {
final_html_string += "</>" + " " + current_word + " ";
last_opening_tag = current_word;
}
}
// if the current_word is a closing tag
else if (current_word.match(/<\/\w+>/)) {
if (last_opening_tag !== null) {
final_html_string += "</>" + " ";
last_opening_tag = null;
}
else {
// do nothing with the current_word,
// let it get swallowed, we want to drop the dangling closing tags
}
}
// else the current_word is a normal word
else {
if (last_opening_tag !== null) {
final_html_string += current_word + " ";
}
else {
// I took assumption here,
// that if we don't have any opening tag, we will use `<p>`
final_html_string += "<p>" + " " + current_word + " ";
last_opening_tag = "<p>";
}
}
}
return final_html_string.trim();
}
abc = "<p> Hello world <em> How are you? </em> abc <em> You there </em> </p>";
console.log(changeHTMLEndTags(abc));
abc = "<p> Hello world<em> How are you? </em> abc <em> You there </em> </p>";
console.log(changeHTMLEndTags(abc));
Upvotes: 2
Reputation: 11613
There might be a fancier way to do this, but this works to replace </em>
and </p>
with </>
, which seems to be your goal (despite the inconsistencies in your question and sample output).
let string = "<p> Hello world <em> How are you? </em> abc <em> You there </em> </p>";
let def = string.replace(/<\/(em|p)>/g, "</>");
console.log(def);
Upvotes: 0