Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нем неправильно. Необходимо обновить браузер или попробовать использовать другой.
Да, но как ее правильно вписать.. рекурсии можно добавлять через (?номер) - в 3.3.12.0 добавили возможность.
Только я не могу понять как их использовать для этого случая..
DarWiM
Нужно распарсить html страницы. И нужно быстро, страниц много.
Пробую через ObjCreate('HTMLFILE'), но только на то что бы загрузить станицу в объект, уже тратится целая секунда.
И поэтому хочу попробовать через регулярные варажения, может будет быстрее.
Ух ты, здорово! Проверил на реальной странице, все заработало! C2H5OH, да, ты крут! А я вот не смог понять. (даже с этим примером )
Самое интересное, это первый пример регулярки с рекурсией.
Спасибо огромное.
Ты думаешь я два дня чем занимался?
В справке одни намёки отдалённые...
Вот сегодня наконец допёр что надо для рекурсии в самой субрутине не (?R) ставить, а (?&имя)
А с этим примером то что не понятно?
Добавлено:
Сообщение автоматически объединено:
Кстати, а по времени как? Регулярка даёт ощутимый выигрыш?
Еще как!
Если загружать в объект, то нужно подождать пока документ полностью не запишется, а это у меня занимает около 1 секунды.
Потом мне нужно найти $document.getElementsByClassName('listEntry'), получить коллекцию, по которой нужно пройтись, что бы доставать необходимую информацию.
А с регуляркой, я сразу получаю массив, и всего за 12 миллисекунд.
Выигрыш огромный!
Сначала алгоритм.
Вот мы нашли в тексте имя тега <div (вторая скобка '>' не написана специально, сами догадайтесь почему)
Что может встретиться внутри этого тега между <div и </div> ?
Либо ещё такой же тег <div - </div> , либо другой совершенно произвольный символ.
Если встретилось начало такого же тега <div , то мы, естественно, делаем рекурсивный вызов шаблона, потому что перед нами встаёт такой же вопрос "а что может быть внутри?".
<div(?&tag)*?</div>|. - сам шаблон субрутины с рекурсивным вызовом: либо вложенный тег <div - </div>, либо какой-то символ.
Где (?&tag) - собственно рекурсивный вызов субрутиной самой себя.
<div class="listEntry">(?&tag)*?</div> - основной паттерн, который делает первое обращение к рекурсивной субрутине.
<div(?&tag)*?</div>|.
Вот эта часть. Это тело субрутины? Как оно ищет:
Ищем <div затем пытаемся вызввать субрутину (<div?) т.е <div<div<div<div итп?, а если нет, то любой символ, скажем <div . а тут опять пробуем найти <div рекурсивно.
Между <div и СООТВЕТСТВУЮЩЕМУ ЕМУ </div> N раз встречается что-то, совпадающее с шаблоном субрутины.
Это что-то может быть одиночный символ '<div(?&tag)*?</div>|.' <- '.'
Либо такой же тег <div -- </div>.
Если это тег <div -- </div>, то внутри его M раз встречается что-то, совпадающее с шаблоном субрутины, поэтому мы внутри вызываем рекурсивно сам этот же шаблон
<div(?&tag)*?</div>
А сколько символов или вложенных тегов может быть внутри <div -- </div> ?
Вот столько
<div(?&tag)*?</div>
Хотя продолжать разговор в теме, которая помечена как решенная и является дурным тоном, но у нас на форуме впервые обсуждается рекурсия в регулярных выражениях. И обсуждается не теоретически, а на реальном примере. И надо разобраться что и как. Поэтому давайте продолжим.
Почему нам не подходит схема паттерна как в примере с круглыми скобками?
{(?:[^{}]*+|(?0))*}
Этот паттерн находит все рекурсивные блоки заключенные в {}.
Но скобки самого верхнего уровня равнозначны внутренним скобкам. И поэтому тут применим рекурсивный вызов всего паттерна (?0) или (?R).
Но у нас div верхнего уровня отличается, он содержит class="listEntry"
И если мы напишем аналогичный скобочному паттерн для div, примерно так
То такой паттерн вернёт нам нужные теги, но только потому, что в тестовых данных, приведённых ТС в самом начале, теги <div class="listEntry"> являются тегами верхнего уровня. Что в реальной ситуации маловероятно. Скорее всего исходные данные будут иметь вид
И результатом работы такого паттерна будет самый верхний тег div, то есть вся страница, которую мы хотим обработать.
Так что паттерн
Код:
$pattern = '(?s)<div(?:(?0)|.)*?</div>'
не смотря на краткость и изящность, к сожалению, не решает нашу задачу. :(
Но что интересно в примере с круглыми скобками? (ну, для меня лично, по меньшей мере)
Вызов субрутины по номеру (?0)
нулевая субрутина - это весь паттерн.
Как мы можем это использовать? Отказаться от описания имени в (DEFINE) и делать рекурсивный вызов по номеру.
Вот так
(?(DEFINE) - сейчас будет описание субрутины (ПЕРВОЙ по порядку)
(<div(?1)*?</div>|.) - сам шаблон субрутины с рекурсивным вызовом субрутины первой по порядку во всём шаблоне (?1).
Ну, вроде бы шаблон по длинне меньше чем с именованной субрутиной, но скорость работы очевидно что одинаковая.
Облегчает ли понимание использование номеров субрутин вместо имён? Это уж кому как нравится.