Как составить регулярное выражение для парсинга html?

Есть html который содержит в себе такой код для примера

<h3 id="z000"> 1. ОБЩИЙ СОСТАВ<br>РАЗДЕЛ 1. ОБЩИЕ ПОЛОЖЕНИЯ<br>Глава 1. ОСНОВНЫЕ ПОЛОЖЕНИЯ Часть 1. Тестовый заголовок</h3>
<p id="z1">      <b>Часть 16</b>. Размещение центра по траектории <br></p>
<h3 id="z001"> Часть 2. Положение гироскопа</h3>
<b><a name="z123"></a>  Часть 88. Определение системы соотношении</b>
<b><a name="z133"></a>  Часть 52. Определяем угол</b>

Пытаюсь пропарсить через preg_match_all с таким правилом

<(h3|p|a).*((id|name)="(z[0-9]+)"|).*>(.*)(РАЗДЕЛ|Раздел|раздел|ГЛАВА|Глава|глава|ЧАСТЬ|Часть|часть)(.*)(?(?=<\/a>)(.*)((<\/)b(>))(?!<b>)|<\/(h3|p)>)

выводит результат https://www.phpliveregex.com/p/Gcx это делаю для того чтобы создать навигацию по блокам текста, по стандарту навигацию надо по "h3", "p" сделать, есть еще учитывать, то что есть и такой паттерн

<b><a name="z123"></a>#ТУТ_ТЕКСТ#</b>

если посмотрите на примере, то, там последний паттерн кое как сделал, но, он почему то берет и следующий такой текст если таковой существует.

Как сделать регулярку чтобы последнее вот до

</b>

только бралось? Или как можно улучшить вот это все с учетом того что, для такого паттерна

<b><a name="z123"></a>#ТУТ_ТЕКСТ#</b>

я делаю замену с добавлением id рядом с name


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

Автор решения: m.sultan

Сам сделал регулярку чтобы вытащить такие html тэги.

(<b>|)<(p|a|h3).*((id|name)=\"(z[0-9]+)\")(.*)*>(.*)(?(?=<\/a>)<\/a>(.*)<\/b>|<\/(p|h3)>)

не могу использовать готовые библиотеки, т.к. просто напросто мне надо вытащить массив обработать их в цикле в ul li закинуть. Чем использовать эти готовые решения что портят время отрисовки страниц.

Всем спасибо за непомощь!

→ Ссылка