简体   繁体   中英

PHP Regex - Matches multiple items after Positive Lookbehind

I have this HTML

<ul class="my-list"><li>Item1</li><li>Item2</li><li>Item3</li></ul>

<ul class="other-list"><li>ItemA</li><li>ItemB</li><li>ItemC</li></ul>

I want to get each <li> that's under the class "my-list" and tried to use Positive Lookbehind like this:

preg_match_all( '/(?<=my-list">).*(<li>.+<\/li>)/Ui', $text, $matches );

But I only get the first <li> like this:

array(
  0 => array(1
    0 => <li>Item1</li>
  )
)

How to get each of the list item? Expected result:

array(1
  0 => array(1
    0 => <li>Item1</li>
    1 => <li>Item2</li>
    2 => <li>Item3</li>
  )
)

Thanks

You should really be using a parser instead:

<?php

$data = <<<HTML
<ul class="my-list"><li>Item1</li><li>Item2</li><li>Item3</li></ul>

<ul class="other-list"><li>ItemA</li><li>ItemB</li><li>ItemC</li></ul>
HTML;

$dom = new DOMDocument();
$dom->loadHTML($data);

$xpath = new DOMXPath($dom);
foreach ($xpath->query("//ul[@class = 'my-list']/li") as $node) {
#                                             ^^^
    echo $node->nodeValue . "\n";
}

?>

Which yields

Item1
Item2
Item3

See here for more information . Alternatively, this project looks interesting as well.


As for changing (editing) values, just change a few lines:

$xpath = new DOMXPath($dom);
foreach ($xpath->query("//ul[@class = 'my-list']/li") as $node) {
    $node->nodeValue .= "###";
}

$dom->formatOutput = true;
echo $dom->saveHTML();

Then change eg the node value of an element and output it afterwards:

<ul class="my-list">
<li>Item1###</li>
<li>Item2###</li>
<li>Item3###</li>
<ul class="other-list">
<li>ItemA</li>
<li>ItemB</li>
<li>ItemC</li>
</ul>
</ul>

This will yield

<ul class="my-list"> <li>Item1###</li> <li>Item2###</li> <li>Item3###</li> <ul class="other-list"> <li>ItemA</li> <li>ItemB</li> <li>ItemC</li> </ul> </ul>
$text='<ul class="my-list"><li>Item1</li><li>Item2</li><li>Item3</li></ul>

<ul class="other-list"><li>ItemA</li><li>ItemB</li><li>ItemC</li></ul>';

preg_match( '/<ul class="my-list">(.*?)<\/ul>/i', $text, $matches );
preg_match_all( '/(<li>.+<\/li>)/Ui', $matches[0], $matches1 );

var_dump($matches1[0]);

Result:

array(3) {
  [0]=>
  string(14) "<li>Item1</li>"
  [1]=>
  string(14) "<li>Item2</li>"
  [2]=>
  string(14) "<li>Item3</li>"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM