регулярное выражение, проверка присутствия в теге <table>

программирование php html регулярные выражения

есть приблизительно такой текст
=========
<span>вот так</span>
<table>
<tr>
<td>
<p>Начало</p>
<p>ненужный текст</p>
</td>
</tr>
</table>
<p>пусто</p>
<span>трали вали</span>
<p>Начало единственного правильного места</p>
<p> нужный текст</p>
<table>
<tr>
<td>
<span>тут текст мешающий найти тэг td, может быть бесконечно много</span>
<p>Начало</p>
<p>ненужный текст</p>
</td>
</tr>
</table>
<p>тут начало текста ненужного
начало не нужного текста</p>
==============
хочу разрезать его на 2 части(preg_split), все до <p>Начало единственного правильного места</p> и все после
применяю сейчас такую регулярку
(?=(<\w+>|\s))(?=\1Начало) //я его сильно упростил что бы было наглядно, модификаторы юникода и без учета регистра

Проблема в том что не должно разрезать то что находиться внутри таблицы. В идеале регулярку нужно улучить проверкой что вначале нету НЕЗАКРЫТОГО тега <table>, тоесть если слово "Начало" находиться гдето глубоко между тегами <table></table> то должно не выполняться поиск. Ретроспективная негативная проверка тут не помогает, так как имеет сильные ограничения поиска в pcre

Мои мысли такие, нужно как пропускать текст внутри таблицы в поиске "Начало"

Примечание:
если бы можно было использовать разбор дума я бы так и сделал. Регулярки уже умеют пользоваться рекурсией, так что ответ не должен быть слишком сложный. И скорость выполнения не имеет значения

Примечание:
пришел вот к такому коду
%(?P<nach>начало)|(?:(?P<table><table>(?:(?!<table>)[^<]+|(?P>table)|\X)+?</table>))%siu
но он мне помогает только тем что я могу выловить нужный мне результат в именновой группе, но для сплитта это не подходит так как в общую выборку попадают и таблицы

Примечание:
если бы у меня был доступ напрямую к пхп я могбы уже решить свою задачу, приблизительно так
preg_match_all('%(?P<nach>начало)|(?:(?P<table><table>(?:(?!<table>)[^<]+|(?P>table)|\X)+?</table>))%siu', $subject, $result,PREG_OFFSET_CAPTURE);
$split_pos = array();
array_walk_recursive($result['nach'], function($v, $k) use (&$split_pos){
if (is_numeric($v) && $v>0){
$split_pos[] = $v;
}
});
это дает мне позииции мест для разреза. Это ответ для тех кому это подходит. Я же буду искать дальше
Ответы:
Мои мысли такие, что вы шваброй котлован копаете. Может лопату возьмете?


13 лет назад

RPI.su - самая большая русскоязычная база вопросов и ответов. Наш проект был реализован как продолжение популярного сервиса otvety.google.ru, который был закрыт и удален 30 апреля 2015 года. Мы решили воскресить полезный сервис Ответы Гугл, чтобы любой человек смог публично узнать ответ на свой вопрос у интернет сообщества.

Все вопросы, добавленные на сайт ответов Google, мы скопировали и сохранили здесь. Имена старых пользователей также отображены в том виде, в котором они существовали ранее. Только нужно заново пройти регистрацию, чтобы иметь возможность задавать вопросы, или отвечать другим.

Чтобы связаться с нами по любому вопросу О САЙТЕ (реклама, сотрудничество, отзыв о сервисе), пишите на почту [email protected]. Только все общие вопросы размещайте на сайте, на них ответ по почте не предоставляется.