Search code examples
javascripthtmlregexregex-group

How to replace HTML span opening and closing tag that has specific class name with div tag


I have this HTML code

<span class="line"><span>// Before</span></span> 
<span class="line">
  <span>import</span>
<span> </span><span>db</span>
<span> </span><span>from</span><span>    </span>
  <span>'../../lib/db-admin'</span><span>;</span>
</span> 
<span class="line"><span>// After</span></span> 
<span class="line"><span>import</span>
<span> </span><span>db</span><span> </span>
<span>from</span><span> </span>
<span>'lib/db-admin'</span><span>;</span></span>

I would like to replace every opening and closing span tag with class="line" with the div tag. How can i do it using regular expressions?

This is what i've already tried, but cannot get it until working condition.

/(<span class="line">.*?<\/span>)\s*<span class="line">(.*?)<\/span>((?!<\/span>).)*<\/span>/g, '$1</div><div class="line">$2</div>'

Solution

  • Don't use a regex to analyse/parse an HTML string. Instead use a DOM parser. You can use DOMParser and do this:

    function replaceWithDivs(html, selector) {
        const doc = new DOMParser().parseFromString(html, "text/html");
        for (const elem of doc.querySelectorAll(selector)) {
            const div = doc.createElement("div"); // Create the new element
            div.innerHTML = elem.innerHTML;       // Copy the contents
            elem.replaceWith(div);                // And replace old with new
        }
        return doc.body.innerHTML;
    }
    
    // demo
    let html = `<span class="line"><span>// Before</span></span> 
    <span class="line">
      <span>import</span>
    <span> </span><span>db</span>
    <span> </span><span>from</span><span>    </span>
      <span>'../../lib/db-admin'</span><span>;</span>
    </span> 
    <span class="line"><span>// After</span></span> 
    <span class="line"><span>import</span>
    <span> </span><span>db</span><span> </span>
    <span>from</span><span> </span>
    <span>'lib/db-admin'</span><span>;</span></span>`;
    
    html = replaceWithDivs(html, "span.line");
    console.log(html);