-3

We have a HTML string where we have a list. Something like shown below

<ul><li>Item A</li><li>Item B</li><li>Item C</li><li>Item D</li></ul>

Here is the formatted version of the same.

<ul>
   <li>Item A</li>
   <li>Item B</li>
   <li>Item C</li>
   <li>Item D</li>
</ul>

My objective is to write a regular expression to select the first two items for the list. So the output should be

<ul>
   <li>Item A</li>
   <li>Item B</li>
</ul>

If that's not possible to do it in regex, what will be a most optimized way to do it through plain javascript code.

Phil
  • 157,677
  • 23
  • 242
  • 245
Alex
  • 1,406
  • 2
  • 18
  • 33
  • I think this should help answered here: [REGEX match x times](https://stackoverflow.com/questions/6731359/regex-match-x-times-li-anything-in-here-li) – tylerjames Apr 20 '22 at 04:37
  • What should the result of this be? An HTML string or an actual element / document fragment? – Phil Apr 20 '22 at 04:45
  • @Phil It should be string with
      and match
    • s
    – Alex Apr 20 '22 at 04:46

2 Answers2

3

Don't use a regex for this. Parse the HTML into a document fragment and use DOM methods to remove the elements

const html = `<ul><li>Item A</li><li>Item B</li><li>Item C</li><li>Item D</li></ul>`;

const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");

// Remove all <li> elements after the 2nd
doc.querySelectorAll("li:nth-child(n+3)").forEach(el => el.remove());

// DOMParser puts the HTML fragment into the created document body
const newHtml = doc.body.innerHTML;

console.log(newHtml);

This also works with end-tag omission like this...

<ul>
   <li>Item A
   <li>Item B
   <li>Item C
   <li>Item D
</ul>

which is potentially something a regular expression could really struggle with.

Phil
  • 157,677
  • 23
  • 242
  • 245
0

You can do:

const str = `<ul><li>Item A</li><li>Item B</li><li>Item C</li><li>Item D</li></ul>`
const re = tag => new RegExp(`<${tag}>(.*?)<\/${tag}>`, 'g')
const ul = str.replace(re('ul'), ($1, $2) =>
  $1.replace($2, $2.match(re('li')).slice(0, 2).join(``)))

console.log(ul)
Yosvel Quintero
  • 18,669
  • 5
  • 37
  • 46