-2

I try to make a regex that only matches list elements over multiple lines with one <li></li> tag. For example:

<ul>
    <li>
        Test, Test
    </li>
</ul>

this should match, but this:

<ul>
    <li>
        Test, Test
    </li>
    <li>
        Test, Test
    </li>
</ul>

should not.

I already have

<ul>(.*?)<li>(?!<li>)<\/li>(.*?)</ul>

but this don't have a match at all anymore.

Does anybody know how to achieve this?

John Conde
  • 217,595
  • 99
  • 455
  • 496
Thomas
  • 1
  • 3
  • Why do this with a RegExp instead of a DOM parser? – Barmar Jan 22 '21 at 00:30
  • 1
    Don't use regex to parse HTML. Instead use a proper tool like [`DOMDocument`](https://www.php.net/manual/en/class.domdocument). See https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags?rq=1 – Nick Jan 22 '21 at 00:30
  • The reason is i want to replace all lists with one element with p tags – Thomas Jan 22 '21 at 08:47

1 Answers1

0

Don't use regexes for parsing HTML. Here's how to do it without a Regex:

$html = [
'<ul>
    <li>
    Test, Test
    </li>
        <li>
    Test, Test
    </li>
</ul>',
'<ul>
    <li>
    Test, Test
    </li>
</ul>',
];

$previous_value = libxml_use_internal_errors(true);

$dom = new DOMDocument();
foreach($html as $list) {
    $dom->loadHTML($list);
    echo $dom->getElementsByTagName('li')->length . "\n";
}

libxml_clear_errors();
libxml_use_internal_errors($previous_value);

Demo

This code parses the HTML itself and gets all of <li> elements and then simply counts them.

John Conde
  • 217,595
  • 99
  • 455
  • 496