-1

I'm trying to add html markup to an unordered list with a specific class.

This would be the HTML to start with:

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>    
<ul class="foo">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

And I would like to end up with:

<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>    
<ul class="foo">
  <li><svg class="icon"><use xlink:href="#foo"></use></svg>Item 1</li>
  <li><svg class="icon"><use xlink:href="#foo"></use></svg>Item 2</li>
  <li><svg class="icon"><use xlink:href="#foo"></use></svg>Item 3</li>
</ul>

I haven't found a regex that could be used to run a preg_replace() that can get this to work.

The content is created with Wordpress. I want to use a filter that scans the_content and adds the extra markup. In such a manner:

function foo_ul($text) {
    //some function
    return $text;
}
add_filter('the_content', 'foo_ul');

I do not want to be reliant on Javascript/jQuery so I would like this to be generated on the server-side.

Any ideas?

Jasper
  • 1
  • 2
  • A you sure it's a best way to use php and regexp for this task? – Oleg Nurutdinov Nov 26 '18 at 14:28
  • 1
    If you are doing this serverside, I would use a html parser rather than a regex but we would need to know more info - what creates the list? how do you know what class it has? surely if the list is created serverside with php, then you can just add the svg then, etc. In it's current form, the question is too broad and therefore off topic for SO - please take a [tour](https://stackoverflow.com/tour) of the [help centre](http://stackoverflow.com/help) to see [how to ask a good question](http://stackoverflow.com/help/how-to-ask) – Pete Nov 26 '18 at 14:28
  • The content is generated by Wordpress so I'd like to add a filter that scans the content and adds the desired markup in the right places. – Jasper Nov 26 '18 at 14:32
  • Are you looking something like this: https://regex101.com/r/QkWsfU/1 – Amrendra Kumar Nov 26 '18 at 14:34
  • could use js and do it clientside - would probably be easier than writing something to intercept the plugin code serverside – Pete Nov 26 '18 at 14:36
  • @Pete I'm definitely not sure that regex is the best solution. I've not yet worked with HTML parsers, so if somebody here is, please send me in the right direction :) – Jasper Nov 27 '18 at 13:46
  • It's pretty simple, you just pass your text into the parser and if it's valid html, you can query it and the work with the result: http://htmlparsing.com/php.html and https://stackoverflow.com/questions/3577641/how-do-you-parse-and-process-html-xml-in-php – Pete Nov 27 '18 at 13:52

1 Answers1

1

Using regex for matching HTML isn't good as you can see in question. However if your string is that you shown in OP you can use this regex pattern that select every string between <li></li> and add target string to it.

$newHtml = preg_replace("/(?<=<li>)(.*)(?=<\/li>)/", '<svg class="icon"><use xlink:href="#foo"></use></svg>$1', $html);

Check result in demo


Update: If you have multiple ul and want to match only .foo use this code

$newHtml = preg_replace_callback("/(?<=<ul\sclass=\"foo\">).*?(?=<\/ul>)/s", function($ma){
    return preg_replace("/(?<=<li>)(.*)(?=<\/li>)/", '<svg class="icon"><use xlink:href="#foo"></use></svg>$1', $ma[0]);
}, $html);

Check result in demo

Mohammad
  • 21,175
  • 15
  • 55
  • 84