3

I have this list:

<ul>
    <li class="myclass">blablabla 1</li>
    <li class="myclass">blablabla 2</li>
    <li class="myclass">blablabla 3</li>
</ul>

And I want, with a regex, this:

<div class="newClass">blablabla 1</div>
<div class="newClass">blablabla 2</div>
<div class="newClass">blablabla 3</div>

Replacing only <li> works, with this regex:

$pattern = '#<li class="newClass">(.+)</li>#';
$replacement = '<div class="newClass">$1</div>';
$texte = preg_replace($pattern, $replacement, $texte);

I tried to replace the <ul> too, but it doesn't work:

$pattern = '#<ul>(<li class="myclass">(.+)</li>)*</ul>#';
$replacement = '<div class="newClass">$2</div>';
$texte = preg_replace($pattern, $replacement, $texte);

What is wrong?

Biffen
  • 6,249
  • 6
  • 28
  • 36
RenishV8
  • 146
  • 1
  • 12

2 Answers2

2

Your pattern is almost correct.

$pattern = '#<ul>(<li class="myclass">(.+)</li>)*</ul>#';

Although, there are multiple flaws in your pattern.

  • <ul> will assume that all your <li ... will start with <ul> which is not the case for <li class="myclass">blablabla 2</li>. So, you have to use it with ? and preferrably in a non capturing group.. i.e. (?:<ul>)? and similarly at the end (?:<\/ul>)? (note the escape character)

  • You are not checking for spaces and newlines before/after <li.. which should be changed to (\s*<li class="myclass">(.+)<\/li>\s*)

  • Also, no need to add * after (<li ...>...<\/li>)

Working modification of your pattern would be (?:<(?:ul|ol)>)?(\s*<li class="myclass">(.+)<\/li>\s*)(?:<\/(?:ul|ol)>)?

See demo for more explanation and exploration.

karthik manchala
  • 13,492
  • 1
  • 31
  • 55
  • Thanks a lot for explanations. It works but if i have another list as :
    1. ...
    The li are also replaced. There is no way to make this regex only for
  • inside
      and not inside
      ?
  • – RenishV8 Apr 13 '15 at 11:25
  • This regex almost works : (?:
      )(\s*
    • (.+)<\/li>\s*)*(?:<\/ul>) But it replaced all my list by one div. I updated the regex page : https://regex101.com/r/rK0yE7/4
    – RenishV8 Apr 13 '15 at 12:34
  • No.. it matches only last capturing group. – karthik manchala Apr 13 '15 at 12:35
  • There is no solution to match all the list ? As a "loop", line per line ? – RenishV8 Apr 13 '15 at 12:45
  • There is.. but prefix and suffix here will not match per line.. either it is complicated and i have to learn more.. looking into it.. – karthik manchala Apr 13 '15 at 13:03
  • I'm looking for it. If i find i'll post it. Anyway thx a lot for your help :) – RenishV8 Apr 13 '15 at 13:12