Регулярное выражение смотрящее назад - чтоэто и как его сделать ?

FidaSa

Постоялец
Регистрация
1 Мар 2013
Сообщения
511
Реакции
145
Доброй ночи.

Нужно для программы сделать регулярное выражение, для поиска определенного фрагмента в html коде.
Сложность в том что код имеет похожую структуру, и поэтому надо использовать регулярное выражение смотрящее назад, что это с трудом представляю.

Есть тут кто с головой и понимает ?

Вот такой мануал гугл выдал -, но понятнее не стало!
Скрытое содержимое доступно для зарегистрированных пользователей!


но как заставить регулярку искать справа, налево, не понятно!

Пример кода схематично.

<a class="spin" lalal54agla </a></div>
<a class="spin" зззз45ззa </a></div>
<a class="spin" pppp5ggp </a></div><ul class="zuk">
<a class="spin" xezx455cg </a></div>
<a class="spin" htrdg45rh </a></div><ul class="zuk">
<a class="spin" lyy45yyyy </a></div>
<a class="spin" la5f45fff45 </a></div><ul class="zuk">

Нужно чтобы регулярка находила вот такие куски
<a class="spin" la5f45fff45 </a></div><ul class="zuk">
<a class="spin" htrdg45rh </a></div><ul class="zuk">
<a class="spin" pppp5ggp </a></div><ul class="zuk">

А вот такие не трогала:
<a class="spin" lalal54agla </a></div>
<a class="spin" зззз45ззa </a></div>
<a class="spin" lyy45yyyy </a></div>
<a class="spin" xezx455cg </a></div>
 
Код:
<a.*?<ul\ class="zuk">
 
Последнее редактирование:
Код:
<a.*?<ul\ class="zuk">
Сорри, я тупанула, в примере разбила код на строки, хотя они должны быть все в одну строку, в этом то и сложность.

Вот такой пример кода:

<a class="spin" lalal54agla </a></div><a class="spin" зззз45ззa </a></div><a class="spin" pppp5ggp </a></div><ul class="zuk"><a class="spin" xezx455cg </a></div><a class="spin" htrdg45rh </a></div><ul class="zuk"><a class="spin" lyy45yyyy </a></div><a class="spin" la5f45fff45 </a></div><ul class="zuk">


Нужно чтобы регулярка находила вот такие куски
<a class="spin" la5f45fff45 </a></div><ul class="zuk">
<a class="spin" htrdg45rh </a></div><ul class="zuk">
<a class="spin" pppp5ggp </a></div><ul class="zuk">

А вот такие не трогала:
<a class="spin" lalal54agla </a></div>
<a class="spin" зззз45ззa </a></div>
<a class="spin" lyy45yyyy </a></div>
<a class="spin" xezx455cg </a></div>
 
  • Нравится
Реакции: dmx
Код:
<a\ class="spin"\ [a-z0-9]+\ </a></div><ul.*?"zuk">
тогда может так, но ерунда
 
Код:
<a\ class="spin"\ [a-z0-9]+\ </a></div><ul.*?"zuk">
тогда может так, но ерунда
Неа, не пройдет, проблема в том, что эти части текста очень похожи, разница только на хвосте текста, поэтому невозможно установить интервал, стандартным способом, который смотрит вперед, так как у них начало и содержимое одинаковое, и отличается только окончание, и они еще в одной строке.

Пришлось разбить на строки и подругому сделать, через задницу (как обычно:) ), но вопрос для меня актуален:

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

Чтобы оно сначала искало текст "<ul class="zuk">" и от него, шло налево, в сторону начала кода, то есть "назад" до первого встретившегося текста
"<a"
 
А если захват от <a до ближайшего </a></div><ul class="zuk">
Код:
<a((?!</a).)+</a></div><ul class="zuk">
Для просмотра ссылки Войди или Зарегистрируйся
 
А если захват от <a до ближайшего </a></div><ul class="zuk">
Код:
<a((?!</a).)+</a></div><ul class="zuk">
Для просмотра ссылки Войди или Зарегистрируйся
Спасибо, но нужен захват от "<ul class="zuk">" , до ближайшего "<a", в левую сторону (то есть "назад" до первого встретившегося текста" <a")
 
во-первых у вас там открывающий тег A не закрыт. это может вводить в заблуждение. и вообще непонятно что такое la5f45fff45 - текст ссылки, анкор или какой то атрибут?
во-вторых регулярные выражения не смотрят ни вперед ни назад. а лишь ищут текст согласно заданного вами шаблона
если нужна ссылка перед UL, может попробовать так:
Код:
(<a.*?>(.*?)</a>)</div><ul class="zuk">
если такой паттерн задать в функцию preg_match_all то она вернет массив, в которой будут и весь блок
Код:
<a...>...</a></div><ul class="zuk">
и вся ссылка
Код:
<a...>...</a>
и текст внутри ссылки
<a...>...</a>
 
во-первых у вас там открывающий тег A не закрыт. это может вводить в заблуждение. и вообще непонятно что такое la5f45fff45 - текст ссылки, анкор или какой то атрибут?
во-вторых регулярные выражения не смотрят ни вперед ни назад. а лишь ищут текст согласно заданного вами шаблона
если нужна ссылка перед UL, может попробовать так:
Код:
(<a.*?>(.*?)</a>)</div><ul class="zuk">
если такой паттерн задать в функцию preg_match_all то она вернет массив, в которой будут и весь блок
Код:
<a...>...</a></div><ul class="zuk">
и вся ссылка
Код:
<a...>...</a>
и текст внутри ссылки
<a...>...</a>
Как так нету :) , а это тогда о чем Lookbehind
Скрытое содержимое доступно для зарегистрированных пользователей!
 
Ретроспективная проверка (?<= ), (?<! ) как раз выполняет просмотр назад, но сперва нужно уточнить для какой прграммы составляется выражение т.к. в большинстве реализаций устанавливается ограничение на длину текста при ретроспективной проверке.
Код:
(?<=(<a.+?</a></div>))<ul class="zuk">
В Perl, PHP, Python такое не работает.
Работает в языках платформы .NET например C#.
Тестирование регулярок для .NET Для просмотра ссылки Войди или Зарегистрируйся
Самые жесткие правила действуют в Perl и Python, где ретроспективная проверка ограничивается строками фиксированной длины. Например, конструкции (?<!\w) и (?<!this|that) допустимы, a (?<!books?) и (?<!^\w+: ) запрещены, поскольку они могут совпадать с текстом переменной длины. В таких случаях, как с (?<!books?), задача решается выражением (?<!book)(?<!books), но понять его с первого взгляда весьма непросто.

На следующем уровне поддержки в ретроспективной проверке допускаются альтернативы разной длины, поэтому выражение (?<!books?) может быть записано в виде (?<!book|books). PCRE (и все функции рreg в РНР) это позволяют.

На следующем уровне допускаются регулярные выражения, совпадающие с текстом переменной, но конечной длины. Например, выражение (?<!books?) разрешено, а выражение (?<!^\w+: ) запрещено, поскольку совпадение \w+ может иметь непредсказуемую длину. Этот уровень поддерживается пакетом регулярных выражений для Java от Sun.

Справедливости ради стоит заметить, что первые три уровня в действительности эквивалентны, потому что все они могут быть выражены, хотя и несколько громоздко, средствами минимального уровня (с фиксированной длиной). Остальные уровни – всего лишь «синтаксическая обертка», позволяющая сделать то же самое более удобным способом.
Впрочем, существует и четвертый уровень, при котором подвыражение в ретроспективной проверке может совпадать с произвольным объемом текста, поэтому выражение (?<!^\w+: ) является разрешенным. Этот уровень, поддерживаемый языками платформы .NET от Microsoft, принципиально превосходит остальные уровни, однако его неразумное применение может серьезно замедлить работу программы (столкнувшись с ретроспективой, которая может совпадать с текстом произвольной длины, механизм вынужден проверять условие от начала строки, что требует огромного объема лишней работы при проверке в конце длинного текста).

Поэтому предлагал решение задачи без использования (?<= ) Для просмотра ссылки Войди или Зарегистрируйся
Это выражение найдёт <ul class="zuk"> и захватит текст только до ближайшего слева "<a"
 
Последнее редактирование:
Назад
Сверху