0

I'm using this html code

<ul class="nav_1">
    <li>
        <a href="#">Home</a>
        <ul class="submenu_nav_1">
            <li>
                <a href="#">Home</a>
                <ul class="submenu_nav_1_1">
                    <li><a href="#">Home</a></li>
                    <li><a href="#">Menu Item 1</a></li>
                </ul>
            </li>
            <li><a href="#">Menu Item 1</a></li>
        </ul>
    </li>
    <li><a href="#">Menu Item 1</a></li>
    <li><a href="#">Menu Item 2</a></li>
</ul>

<ul class="nav_2">
    <li><a href="#">Home</a></li>
    <li><a href="#">Menu Item 1</a></li>
    <li><a href="#">Menu Item 2</a></li>
</ul>

I want to use php regex to add this html code <li>Text</li> inside <ul class="nav_1"> So the result need to be:

<ul class="nav_1">
    <li>Text</li>
</ul>

<ul class="nav_2">
    <li><a href="#">Home</a></li>
    <li><a href="#">Menu Item 1</a></li>
    <li><a href="#">Menu Item 2</a></li>
</ul>

But when I try this php code :

<?php
    $html  = preg_replace('/(.*?<ul[^>]*?class=[\"|\']nav_1[\"|\'][^>]*>).*(<\/ul>.*)/s','$1'.PHP_EOL.'<li>Text</li>'.PHP_EOL.'$2',$html);
    echo $html;
?>

But this code return:

<ul class="nav_1">
     <li>Text</li>
</ul>
mohamed
  • 173
  • 2
  • 2
  • 14
  • You may have more luck (and overall ease of use) by using the [DOMDocument Class](http://php.net/manual/en/class.domdocument.php). – IncredibleHat Feb 23 '18 at 20:28
  • 1
    This is called parsing. Don't use Regular Expressions for parsing HTML documents. Use a DOM parser instead. – revo Feb 23 '18 at 20:28
  • I would advise to find a way to do it without regex. – NVRM Feb 23 '18 at 20:28
  • 2
    [H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ](https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags) - use a parser – ctwheels Feb 23 '18 at 20:34

2 Answers2

0

As others have said, parsing and manipulating HTML with regular expressions is, while possible, a huge headache.

An alternative is to use the native DOM library. It's pretty straight forward to do minor manipulation:

$html = <<<HTML
<ul class="nav_1">
    <li>
        <a href="#">Home</a>
        <ul class="submenu_nav_1">
            <li>
                <a href="#">Home</a>
                <ul class="submenu_nav_1_1">
                    <li><a href="#">Home</a></li>
                    <li><a href="#">Menu Item 1</a></li>
                </ul>
            </li>
            <li><a href="#">Menu Item 1</a></li>
        </ul>
    </li>
    <li><a href="#">Menu Item 1</a></li>
    <li><a href="#">Menu Item 2</a></li>
</ul>

<ul class="nav_2">
    <li><a href="#">Home</a></li>
    <li><a href="#">Menu Item 1</a></li>
    <li><a href="#">Menu Item 2</a></li>
</ul>
HTML;

// Load original HTML
$dom = new DOMDocument();
$dom->loadHTML($html);

// Find any <ul> with the class "nav_1"
$pathSearch = new DOMXPath($dom);
$ul = $pathSearch->query('//ul[@class="nav_1"]')->item(0);

// Remove the <ul>'s content
while ($ul->hasChildNodes()) {
    $ul->removeChild($ul->firstChild);
}

// Add a new <li> child element with the content "Text"
$ul->appendChild($dom->createElement('li', 'Text'));

echo $dom->saveHTML();

You might need to adjust the XPath query depending on your class structure. This StackOverflow Q&A provides some other options.

Aken Roberts
  • 13,012
  • 3
  • 34
  • 40
-1

By far the easiest way to accomplish what you desire is using JQUERY.

$(".nav_1").html("<li>Text</li>");

And here is a JSFiddle.

https://jsfiddle.net/k9s27rtr/