Отпарска div`а по id или class с учетом вложенных div`ов

Тема в разделе "Регулярные выражения", создана пользователем Inviseble_Demon, 2 авг 2009.

Статус темы:
Закрыта.
Модераторы: xpert13
  1. Inviseble_Demon

    Inviseble_Demon

    Регистр.:
    11 дек 2008
    Сообщения:
    482
    Симпатии:
    350
    Доброго времени суток.​


    Понадобилось написать регулярочку для выдирания div`а с учетом вложенных div`ов....

    PHP:
    $str=file_get_contents('index.html');
    $ser='post';
    preg_match('#<div[\s\w]+[class,id]=[\'"]'.$ser.'[\'"][\s\w]*>.+</div>#smUi'$str$res);

    echo 
    '<pre>';
    print_r($res);
    smUi - согласен что полностью согласен что имеется лишнее :) но пусть пока так останется......

    Трабла в том что как вы видите он идет до первого </div> вследствие чего вложенность теряется, если убрать "U" тоже Ж.па так как гребет до последнего...

    Наверно придется сначало узнать колличество вложенных дивов в требуемый див, дабы прописать количество </div>.!?
    Но вот как это простенько реализовать ума не приложу..

    У меня есть идея, но она мне кажется уж слишком грамоткой и в тоже время что-то подсказывает, что есть более простое решение!?
     
  2. antn

    antn Постоялец

    Регистр.:
    11 июл 2009
    Сообщения:
    104
    Симпатии:
    30
    Это что?)

    Лишь синтаксисом регулярок тут не обойтись. Движок регулярок представления не имеет что такое вложенность и зачем она ему надо. Самое простое - матчить все теги регуляркой ~</?[a-zA-Z]+.*?>~ и дальше методом конечных автоматов: установить глубину = 1, перейти к тегу следующему за искомым, если открывающий, то ++глубина, если закрывающий, то --глубина и так далее. Как только глубина==0, значит найден финальный закрывающий тег.
     
  3. KillDead

    KillDead

    Регистр.:
    11 авг 2006
    Сообщения:
    884
    Симпатии:
    540
    Мне кажется писать это на одной регулярке- не слишком удобно. :nezn:
    Когда доробатывал один граббер тоже понадобилось. В начале обратил внимание на мощный класс php-query. Название говорит само за себя. Но с ним возникли проблемы- отказывался работать, если разметка сильно нарушена.:confused:
    Набрасал такой код
    PHP:
    function get_tag($content$tag$id){
     
      
    $preg '#<'.$tag.'[^>]+id=[\'"]'.$id.'[\'"]#is'
      
    preg_match($preg$content$rezPREG_OFFSET_CAPTURE);
     
    $tag_count=0;
    $return_pos_start$rez[0][1];
    $pos_start_tag $rez[0][1]+1;
    $pos_end_tag strpos($content'</'.$tag.'>'$pos_start_tag);
    $new_cont substr($content$pos_start_tag$pos_end_tag $pos_start_tag);
    $tag_count +=substr_count($new_cont'<'.$tag); 
    while(
    $tag_count){
     
    $pos_start_tag $pos_end_tag
     
    $pos_end_tag strpos($content'</'.$tag.'>'$pos_end_tag+1);
     
    $new_cont substr($content$pos_start_tag$pos_end_tag-$pos_start_tag); 
     
    $tag_count +=substr_count($new_cont'<'.$tag)-1
    }
    return  
    substr($content$return_pos_start$pos_end_tag-$return_pos_start+strlen('</'.$tag.'>'));
     
    }
     
  4. RolCom

    RolCom

    Регистр.:
    12 мар 2008
    Сообщения:
    351
    Симпатии:
    108
    Ошибаетесть.
    Примерно так:
    Код:
    {
    <div[^>]+\b(?:class|id)=["']?foo["']?[^>]*>
     (?:
       (<div[^>]*>(?:(?1)|.)*?</div>)|
       .
     )*?
    </div>
    }xs
    
    Другой вариант - использовать для пасинга DOM
     
    Inviseble_Demon нравится это.
Статус темы:
Закрыта.