Regex php, заменить ul li на div

У меня есть этот список:

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

И я хочу, с регулярным выражением, это:

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

Замена только <li> работает, с этим регулярным выражением:

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

Я пытался заменить <ul> тоже, но это не работает:

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

Что случилось?

3

Решение

Вы можете выполнить все <li> замены за пределами <ol>...</ol> теги со следующим регулярным выражением:

(?(DEFINE)(?<skip><ol>.*?<\/ol>))(?&skip)(*SKIP)(*FAIL)|\s*<li\s+class="myclass">(.*?)<\/li>\s*

(?(DEFINE)                  # We set up conditions
(?<skip><ol>.*?<\/ol>))  # What we skip
(?&skip)(*SKIP)(*FAIL)   # Fail what we skip
|                           # Else, match this
\s*<li\s+class="myclass">(.*?)<\/li>\s*

И замена строки будет:

<div class="newClass">$3</div>\n

Тогда вам просто нужно будет удалить <ul> а также </ul> теги.

Увидеть Основное демо здесь, и Пример программы здесь.

<?php
$str = "<ul>\n    <li class=\"myclass\">blablabla 1</li>\n    <li class=\"myclass\">blablabla 2</li>\n    <li class=\"myclass\">blablabla 3</li>\n</ul>\n<ol>\n    <li class=\"myclass\">blablabla 1</li>\n    <li class=\"myclass\">blablabla 2</li>\n    <li class=\"myclass\">blablabla 3</li>\n</ol>\n<ul>\n    <li class=\"myclass\">blablabla 1</li>\n    <li class=\"myclass\">blablabla 2</li>\n    <li class=\"myclass\">blablabla 3</li>\n</ul>";
$re = "/(?(DEFINE)(?<skip><ol>.*?<\\/ol>))(?&skip)(*SKIP)(*FAIL)|\\s*<li\\s+class=\"myclass\">(.*?)<\\/li>\\s*/s";
$subst = "<div class=\"newClass\">$3</div>\n";
$result = preg_replace($re, $subst, $str);
echo preg_replace("/<\/?ul>/", "", $result);
?>

Выход:

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

<ol>
<li class="myclass">blablabla 1</li>
<li class="myclass">blablabla 2</li>
<li class="myclass">blablabla 3</li>
</ol>
<div class="newClass">blablabla 1</div>
<div class="newClass">blablabla 2</div>
<div class="newClass">blablabla 3</div>
0

Другие решения

Ваш шаблон почти правильный.

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

Хотя в вашем шаблоне есть несколько недостатков.

  • <ul> будет предполагать, что все ваши <li ... начнется с <ul> что не так для <li class="myclass">blablabla 2</li>, Итак, вы должны использовать его с ? и предпочтительно в не захватывающей группе. (?:<ul>)? и так же в конце (?:<\/ul>)? (Обратите внимание побег персонаж)

  • Вы не проверяете пробелы и символы новой строки до / после <li.. который должен быть изменен на (\s*<li class="myclass">(.+)<\/li>\s*)

  • Кроме того, не нужно добавлять * после (<li ...>...<\/li>)

Рабочая модификация вашего шаблона будет (?:<(?:ul|ol)>)?(\s*<li class="myclass">(.+)<\/li>\s*)(?:<\/(?:ul|ol)>)?

Увидеть демонстрация для большего объяснения и исследования.

2

По вопросам рекламы [email protected]