Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Регулярные выражения > Выделить тег с произвольным числом вложенных тегов


Автор: barbiturat 28.12.2009, 13:38
Как в приведенном примере найти <div class="someDiv"> со всем его содержимым при помощи одного регулярного выражения? Это вообще возможно?
Код

    <div class="someDiv">
        <div>...</div>
        <div>...</div>
        <div>
            <div>...</div>
        </div>
    </div>

Автор: sir_nuf_nuf 28.12.2009, 15:37
Ага, возможно:


Код

my $html =<<HTML;
<html>
    <div class="someDiv">
        <div>...</div>
        <div>...</div>
    <br/>
    just a text
        <div>
            <div>...</div>
        </div>
    </div>
    <div>bu</div>
</html>
HTML


$html =~ m{<div[^>]+class="someDiv"[^>]*>             # your div
                (                                     # start recursion
                   (  
                        <\w+[^>]*/>                   # no body, like <br/>
                      | <(\w+)[^>]*>(?1)</\3[^>]*>    # tag with body
                      | [^<]*                         # plain text
                   )*                                 # one or more time
                )                                     # end recursion
           </div>}xs;                                 # be eXplained and Single line


print "found '$&'\n";



P.S. 
Да, такая регулярка поддерживает только xml - стиль - т.е. когда теги либо парные либо самозакрывающиеся. Распарсить старый html типа <b><i></b></i> или <br> не получится.

Автор: n4n0bit 28.12.2009, 17:34
barbiturat http://search.cpan.org/~gaas/HTML-Parser-3.64/Parser.pm

Автор: barbiturat 29.12.2009, 02:30
sir_nuf_nuf, спасибо! Дома попробую.
А что значит (?1)?

Добавлено через 4 минуты и 20 секунд
n4n0bit, мне это нужно для использования не на perl, а на JavaScript. К сожалению, конструкции RegExp на JavaScript-форумах обсуждаются крайне редко, вот и запостил вопрос сюда smile Просто в JavaScript язык регекспов практически полностью совпадает с таковым в perl (хотя в перле и есть свои уникальные конструкции, но их, слава богу, я совсем редко наблюдаю)

Автор: DurRandir 29.12.2009, 08:59
(?1) - это рекурсивный матчинг внутри регулярки (матчит часть этого же самого регулярного выражения рекурсивно, для произвольной вложенности внутренних тегов). Без этого расширения (классическими регулярками) эта задача нерешаема.

Автор: sir_nuf_nuf 29.12.2009, 12:23
Цитата(barbiturat @  29.12.2009,  02:30 Найти цитируемый пост)
мне это нужно для использования не на perl, а на JavaScript

А сразу написать было не судьба ?

(?1) - это означает, что на данном месте нужно опять начать применять кусок регулярки начинаемый в первой (1) группе (круглой скобочек). Рекурсивная регулярка - нововведение perl,
в JavaScript такого нет. 


Зато в JS все решается вообще без регулярок:
Код

alert(document.getElementsByClassName('someDiv')[0].innerHTML;

Правда, здесь только содержимое этого дива.. ну да ладно.

Автор: amg 29.12.2009, 15:00
Цитата(sir_nuf_nuf @  29.12.2009,  12:23 Найти цитируемый пост)
(?1) - это означает, что на данном месте нужно опять начать применять кусок регулярки начинаемый в первой (1) группе (круглой скобочек). Рекурсивная регулярка - нововведение perl
В perl 5.10? То то я смотрю, незнакомая конструкция. А ведь логично и изящно! В старом perl рекурсия регэкспов реализовывалась иначе. Пора переходить на 5.10...

Автор: sir_nuf_nuf 29.12.2009, 15:26
Цитата(amg @  29.12.2009,  15:00 Найти цитируемый пост)
В perl 5.10? 

Ага.. с удивлением обнаружил, что только в 5.10.  В 5.8.8 - нет.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)