Всем заголовкам в тексте добавить атрибут id

Есть текст, хранится в переменной $text, внутри встречаются заголовки . Нужно на php добавить к каждому из них атрибут id по порядку. Например, должно получиться:

<p>Бла-бла-бла</p>
<h2 id="id-1">Заголовок первый</h2>
<p>Бла-бла-бла</p>
<p>Бла-бла-бла</p>
<h2 id="id-2">Заголовок второй</h2>
<p>Бла-бла-бла и т.д.</p>

Вот что написано на данный момент:

    $regularka = '/(.*?)<\/h2>/i';
$matches = array();     
preg_match_all( $regularka, $text, $matches, PREG_SET_ORDER );
$i=1;
foreach ($matches as $elm) {
$text = str_replace('<h2>', '<h2 id="id-'.$i.'">', $text);
$i++;
}   

Но в таком случае ко всем заголовкам прибавляется id-1


Ответы (1 шт):

Автор решения: Алексей Шиманский

В данном случае надо использовать preg_replace_callback

$text = '<p>Бла-бла-бла</p>
<h2>Заголовок первый</h2>
<p>Бла-бла-бла</p>
<p>Бла-бла-бла</p>
<h2>Заголовок второй</h2>
<p>Бла-бла-бла и т.д.</p>';

$regularka = '/(.*?)<\/h2>/i';
$matches = array();     

$i = 1;
$result = preg_replace_callback($regularka, function ($matches) use (&$i) {
    return str_replace('<h2>', '<h2 id="id-'.$i++.'">', $matches[0]);
}, $text, PREG_SET_ORDER );
        
echo $result;        

Но вообще, я бы рекомендовал библиотеку для работы с DOM, например https://www.php.net/manual/ru/class.domdocument.php

Это правильный вариант разбора HTML и замены информации в узлах

→ Ссылка