[Регулярки & Mod_Rewrite] Задай вопрос, получи ответ.

Discussion in 'PHP' started by .:EnoT:., 19 Nov 2008.

Thread Status:
Not open for further replies.
  1. Nek1t

    Nek1t Elder - Старейшина

    Joined:
    7 Mar 2008
    Messages:
    181
    Likes Received:
    16
    Reputations:
    1
    Простая задача на PHP. Для примера беру Хабр. Нужно вытащить с помощью регулярок текст всех комментариев, в которых присутствует некое слово, например, "Windows".
    И вот тут регулярка становится жадной (даже с учетом U) - пожирает лишнего в начале текста. То есть в совпадение попадают фактически все комментарии.
    То есть $maches[1] будет таким:
    Как исправить?
     
    #1561 Nek1t, 24 Aug 2011
    Last edited: 24 Aug 2011
  2. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    Nek1t
    Code:
    #<div class="entry-content-only">([^<>]*Windows[^<>]*)</div>#sU
     
    _________________________
  3. Nek1t

    Nek1t Elder - Старейшина

    Joined:
    7 Mar 2008
    Messages:
    181
    Likes Received:
    16
    Reputations:
    1
    Gifts
    Это скорее костыль, чем решение. Тем более, внутри комментария может быть фактически любой тег (ну, кроме <div class="entry-content-only">). Еще предложения?
     
    #1563 Nek1t, 24 Aug 2011
    Last edited: 24 Aug 2011
  4. astrologer

    astrologer Elder - Старейшина

    Joined:
    30 Aug 2007
    Messages:
    837
    Likes Received:
    267
    Reputations:
    59
    На самом деле это невозможная задача для регулярных выражений. Держи, дальше сам
    Code:
    $pcre = '
    ~
    (?=<div\ class="entry-content-only">)
    (
      <([a-z]+) [^>]*+ >
      (?<post>
        (?:
          [^<]*+
        | <(?:img|hr|br) [^>]*+ >
        | (?1)
        )+
      )
      </\2>
    )
    ~
    ix
    ';
     
    1 person likes this.
  5. Nek1t

    Nek1t Elder - Старейшина

    Joined:
    7 Mar 2008
    Messages:
    181
    Likes Received:
    16
    Reputations:
    1
    Хорошо. А есть какой-то способ задать множество любых строк, не содержащих подстроку <div class="entry-content-only"> ?
     
  6. astrologer

    astrologer Elder - Старейшина

    Joined:
    30 Aug 2007
    Messages:
    837
    Likes Received:
    267
    Reputations:
    59
    Честно:
    Code:
     preg_match('~^(?:[^<]++|(?!<div class="entry-content-only">)<)*$~', $string);
    и нечестно:
    Code:
    !preg_match('~<div class="entry-content-only>~', $string);
     
  7. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    PHP:
    $data '<div class="entry-content-only">
    Коммент1
    </div>
    <p class="reply">
    <...>
    <div class="entry-content-only">
    Коммент2
    </div>
    <...>
    <div class="entry-content-only">
    Коммент 3 со словом Windows
    </div>'
    ;

    if (
    preg_match_all('~<div class="entry-content-only">([\s\S]+?)</div>~i'$data$out)) {
       
    $filtered_out array_filter($out[1], create_function('$var''return is_numeric(stripos($var, "windows"));'));
    }
     
    _________________________
  8. Nek1t

    Nek1t Elder - Старейшина

    Joined:
    7 Mar 2008
    Messages:
    181
    Likes Received:
    16
    Reputations:
    1
    astrologer
    В чем тогда подвох? Почему нельзя воспользоваться этим и написать регулярку вроде #<div class="entry-content-only">([множество_без_entry-content-only]*Windows[множество_без_entry-content-only]*)</div>#sU ?
     
  9. astrologer

    astrologer Elder - Старейшина

    Joined:
    30 Aug 2007
    Messages:
    837
    Likes Received:
    267
    Reputations:
    59
    Code:
    <?php
    
    $html = '
    <div>junk</div>
    <div class="entry-content">
      <div class="entry-content-only">В чем конкретно <i><b>Windows</b></i> стандарт то? </div>
    </div>
    <div>junk</div>
    <div class="entry-content">
      <div class="entry-content-only"> Прежде чем пытаться что то оспорить или навязать</div>
    </div>
    <div>junk</div>
    <div class="entry-content">
      <div class="entry-content-only">
    Углубимся в историю и вспомним что нам <i>назявывали</i></div>
    </div>
    <div>sudden windows junk</div>
    <div class="entry-content">
      <div class="entry-content-only">"Виндоус это не стандарт, не смешите ИТишников". </div>
    </div>
    <div>junk</div>
    <div class="entry-content">
      <div class="entry-content-only"> <div>пытающийся <b>подрожать</b> и уметь <i>тоже</i> что Windows. </div> </div>
    </div>
    ';
    
    preg_match_all('~
    <div\ class="entry-content-only">
    (?:
      [^<w]++
    | (?!<div\ class="entry-content-only">) <
    | (?!windows) w
    )*
    windows
    (?:
      [^<]++ | (?!<div\ class="entry-content-only">) <
    )*?
    </div>
    ~
    ix
    ', $html, $matches);
    
    print_r($matches);
    Так? Оно будет ломаться, как и #1574 на вложенных <div> и на не вложенных тоже, правильного разбора, разумеется, не происходит.
     
  10. Rastamanka

    Rastamanka Elder - Старейшина

    Joined:
    26 Nov 2008
    Messages:
    429
    Likes Received:
    11
    Reputations:
    7
    Помогите спарсить значение contacthome.cfm?
    PHP:
    <div class="tabContainer"><a href="https://www.magnetmail.net/contacts/contacthome.cfm?d=962005005260811">Contacts</a></div>
    В данном примере оно равно d=962005005260811
     
  11. emmy

    emmy Member

    Joined:
    12 Oct 2009
    Messages:
    76
    Likes Received:
    17
    Reputations:
    8
    Code:
    #<a href=".+?contacthome\.cfm\?(d=\d+)">Contacts</a>#
     
  12. попугай

    попугай Elder - Старейшина

    Joined:
    15 Jan 2008
    Messages:
    1,519
    Likes Received:
    401
    Reputations:
    196
    Пытался декодировать подобный скрипток http://pastebin.com/1TBYVsB5 , но проблема возникла на старте - не соображу как регуляркой исполнить base64 и записать уже строку.

    пробовал сделать подобное.
    PHP:
    $f file_get_contents('script.txt');
    echo 
    preg_replace('/base64_decode(.*?\))/e''base64_decode(\\1)'$f);
    не выходит.Модификатор e позволяет же код выполнять.
     
  13. #Wolf#

    #Wolf# Elder - Старейшина

    Joined:
    26 Mar 2008
    Messages:
    375
    Likes Received:
    166
    Reputations:
    16
    PHP:
    echo preg_replace_callback('/base64_decode\((.*?)\)/is',create_function('$t','return base64_decode($t[1]);'),str_replace("' .'",'',$text));
     
    3 people like this.
  14. -=Zhenek=-

    -=Zhenek=- Elder - Старейшина

    Joined:
    31 Dec 2007
    Messages:
    271
    Likes Received:
    77
    Reputations:
    1
    помогите написать регулярку..

    есть структура страницы :

    PHP:
    <td  HEIGHT=30>
     <
    DIV class="display gr1"><span><img src="http://www.site.ru/img/icon_cat_0.gif" border="0"></span><class=menu_link
    title
    ="Автомобили" href="javascript:void(null);">Автомобили</A>
    </
    DIV>
    <
    DIV class=menu_content id=submenu1>


       <
    DIV><A title="Автозапчасти для грузовых автомобилей"
    href="cat/komp2/page0.html">Автозапчасти для грузовых автомобилей</A></DIV>


      
       <
    DIV><A title="Автозапчасти – производство, продажа"
    href="cat/komp3/page0.html">Автозапчасти – производствопродажа</A></DIV>


      
       <
    DIV><A title="Автокосметика"
    href="cat/komp4/page0.html">Автокосметика</A></DIV>

    </
    DIV>
    </
    td>
    То есть сначала категория, потом суб категория..
    Я пытаюсь сначала вытащить все блоки категория+суб категория. а потом из нее вытащить название категории и данные суб.

    PHP:
    $text ccurl("http://site.ru",""); // в итоге в text текст веб страницы. 100% есть
    preg_match_all('#<td  HEIGHT=30>(.*?)</td>#',$text,$m); // получаем в $m блоки которые потом будем парсить
    print_r($m);
    Но массив пустой... вроде что может быть неправильно в регулярке вытащить данные между двумя ТД ? пробовал поразному
     
    #1574 -=Zhenek=-, 3 Sep 2011
    Last edited: 3 Sep 2011
  15. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Народ, не подскажите регулярку чтобы заменить все ссылки на значение из href
    т.е. на входе чтото типа
    Code:
    <tag><a href="DATA1" other_data>Text</a><tag>
    <tag><a        href='DATA2'>Text</a><tag>
    
    на выходе получить
    Code:
    <tag>DATA1<tag>
    <tag>DATA2<tag>
    
    т.е. всю ссылку заменить на значение из href.
    При этому данные могут быть как в кавычках так и в апострофах.
    также ссылка может начинаться на одной строке а заканчиваться на другой.
    типа
    Code:
    <a href="zzz"
    param="val">
    Info
    </a>
    

    т.е. вообще идея такая: нужно убрать из текста все теги но при этому на месте убранного тега <a> чтобы остались на данные внутри которые него, а ссылка
     
  16. Kaimi

    Kaimi Well-Known Member

    Joined:
    23 Aug 2007
    Messages:
    1,732
    Likes Received:
    811
    Reputations:
    231
    Если на perl, то что-нибудь типа

    s/<a\s+href=['"](.+?)['"].*?>.+?<\/a>/$1/sg
     
    _________________________
    1 person likes this.
  17. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    -=Zhenek=- символ точка без модификаторов соответствует любым символам кроме перевода строки, соответственно имея многострочный текст - получить его не получится. Используйте [\s\S] или же модификатор m

    slesh
    PHP:
    $data '<tag><a href="DATA1" other_data>Text</a><tag>
    <tag><a        href=\'DATA2\'>Text</a><tag>'
    ;

    echo 
    preg_replace('~<a[^<>]+href=([\'"])([^\\1]+)\\1[^<>]*>[\s\S]*?</a>~i''\\2'$data);
     
    _________________________
    1 person likes this.
  18. Sc0rpi0n

    Sc0rpi0n Banned

    Joined:
    23 Feb 2010
    Messages:
    75
    Likes Received:
    22
    Reputations:
    16
    Помогите плиз составить регулярку. Вот кусочек.
    Code:
    <a href="http://www.russian.language.ru/test.htm" target="_blank" class="l noline" onmousedown="return rwt(this,'','','','1','AFQjCNE_sDMliZLmfL9c3N-53stLeUXWCw','','0CCYQFjAA')">Study Russian in Russia: Online Russian <em>Test</em></a>
    это один резултьтат из выдачи гугла. таких много причём вокруг ещё куча текста. Я пишу парсер url, помогите плиз регулярку сделать. чтобы была 1) полная ссылка типа http://www.russian.language.ru/test.htm 2) хост www.russian.language.ru
     
  19. Skofield

    Skofield Elder - Старейшина

    Joined:
    27 Aug 2008
    Messages:
    960
    Likes Received:
    392
    Reputations:
    58
    Sc0rpi0n
    PHP:
    <?php
    $str 
    file_get_contents("http://www.google.com/search?q=your+query");
    preg_match_all('#<h3 class="r"><a href="(http://(.*)\/.*)".*</a></h3>#U'$str$match);
    for (
    $i=1$i<=2$i++){
        
    print_r($match[$i]);
    }
    ?>
     
  20. BAGA4

    BAGA4 New Member

    Joined:
    17 Nov 2010
    Messages:
    26
    Likes Received:
    1
    Reputations:
    0
    Помогите с парсингом(Пожалуйста очень надо)

    <div class="popup-box" id="DirectLinks"> <div class="popup-box-btm"> <i>Ваши ссылки <br>для скачивания:</i> <div class="butonz"> <span class="size" title="Размер файла"><b>1 407 Мб</b></span> <a href="#" class="copy" id="1314675559" title="нажмите, чтобы скопировать эту ссылку в буфер обмена">скопировать</a> <a href="http://78.140.178.88/download50/let2309/3836.37e657aaec1bf459bec537349136_1/Let.the.Bullets.Fly.HDRip.avi" class="dwnld" title="нажмите, чтобы начать скачивание в браузере">скачать</a> </div> <span>http://78.140.178.88/download50/let2309/3836.37e657aaec1bf459bec537349136_1/Let.the.Bullets.Fly.HDRip.avi</span> </div> <img src="images/pop-awr.gif" alt="" /> </div>
    С етого кода нужно спарсить вот ету ссылку:
    http://78.140.178.88/download50/let2309/3836.37e657aaec1bf459bec537349136_1/Let.the.Bullets.Fly.HDRip.avi
    И вот ети цифры :1 407 Мб
    Всё вывести в две переменные!Спасибо
     
    #1580 BAGA4, 23 Sep 2011
    Last edited: 23 Sep 2011
Thread Status:
Not open for further replies.