I have a span element with a piece of inner text. I need to target specific pieces of that text through regex and turn my matches into span elements with a class attribute class="hightlight-yellow" and a custom attribute called my-custom-attribute="hello".
Here is my input and expected output…
Input
<span class="message"> This is some text $HIGH:LOW $LOW:HIGH </span>
Output
<span> This is some text <span class="highlight-yellow" my-custom-attribute="hello">$HIGH:LOW</span> <span class="highlight-yellow" my-custom-attribute="hello">$LOW:HIGH</span></span>
How can I do the replace? Here is my current code colleting the matches
function handle()
{
let element = document.getElementsByClassName('message')
let text = element[0].innerText;
let regex = /([^=])\$([A-Za-z:]{1,})/g;
let matches = text.match(regex);
if(matches != null)
{
for(let i = 0; i < matches.length; ++i)
{
// TODO takes matches are replace with spans with attributes.
}
}
}
>Solution :
You can simply use your regex in String.prototype.replace() and replace it with the desired markup wrapping your capturing group.
I have removed the first capturing group since it matches the empty whitespace before, which is not what you want. On top of that, I’d suggest using querySelectorAll and iterate through the node list to future proof your setup.
If you really only want to select the first element that matches the selector .message, that’s also possible.
NOTE: Your output also seems to remove the message class from your original <span> element, but I’m not sure if that is a typo or intentional.
See proof-of-concept below:
function handle() {
const regex = /\$([A-Za-z:]{1,})/g;
document.querySelectorAll('.message').forEach(el => {
el.innerHTML = el.innerText.replace(regex, '<span class="highlight-yellow" my-custom-attribute="hello">$1</span>');
});
}
handle();
span.highlight-yellow {
background-color: yellow;
}
<span class="message">This is some text $HIGH:LOW $LOW:HIGH</span>