Помогите с preg_match_all

Тема в разделе "Как сделать...", создана пользователем 4ksner, 31 май 2013.

  1. 4ksner

    4ksner Постоялец

    Регистр.:
    6 июн 2012
    Сообщения:
    142
    Симпатии:
    60
    Пишу парсер выдачи поиска с одного сайта.
    Выдача:
    Код:
     <a href="/news/detail/[B]NEWS_ID[/B].html"><b>[B]TITLE[/B]</b>
                <p>[B]TEXT[/B]</p>
    и т.д.
    Фильтрую так:
    PHP:
    preg_match_all('|<a href="/news/detail/[B]([^<]+)[/B].html"><b>[B]([^<]+)[/B]</b>|Uis'$data$pages);
    Сначала думал все работает нормально, но потом увидел что косячит с некоторыми заголовками. Оказалось что в некоторых новостях в TITLE выделяют слова тегами <b></b>.
    Пример:

    Код:
    <a href="/news/detail/[B]NEWS_ID[/B].html"><b>[B]TITLE..........[/B]<b>[B]TITLE[/B]</b>[B]TITLE.............[/B]</b>
    Поэтому мой preg_match_all режет заголовок пополам до ближайшего тега </b>.

    Как мне нормально спарсить заголовок с учетом возможного наличия <b></b>?
     
  2. latteo

    latteo Эффективное использование PHP, MySQL

    Moderator
    Регистр.:
    28 фев 2008
    Сообщения:
    1.450
    Симпатии:
    1.239
    Вообще удивительно как это работает...
    Попробуй заэкранировать (поставить слеши "\") перед теми символами, которые используются в регулярках как мета символы http://php.net/manual/ru/regexp.reference.meta.php Потому как сейчас регулярка если и работает, то не так как ты предполагаешь...
    например вот эта часть выражения
    Код:
    [/B].
    - будет искать символ "/" или символ "B" и после него еще один любой символ, кроме перевода строки, что аж никак не соответствует закрывающему bold BB-коду + точка, который в регулярке будет выглядеть как-то так
    Код:
    \[/B\]\.
     
  3. 4ksner

    4ksner Постоялец

    Регистр.:
    6 июн 2012
    Сообщения:
    142
    Симпатии:
    60
    Исходник:

    HTML:
     <a href="/news/detail/NEWS_ID.html"><b>TITLE</b>
    <p>TEXT</p></a>

    Не заработал preg_match_all.
    Начал пробовать через Simple HTML DOM.
    Сделал вот такой код:
    PHP:
    foreach($html->find('div.search-page') as $div) {
    foreach(
    $div->find('a[href^=/news/detail/]') as $a) {
    echo 
    $a->first_child() . '<br>';
    }
    }
    first_child() обрабатывает первый тег <b>. Но блин когда в TITLE есть еще один <b>, то он все-равно режет заголовок.

    При этом мне выводится полная структура между тегами a:

    Ни чего не находит, как я понимаю из-за того, что после закрывающего тега b, есть еще p:



    Помимо заголовков без <b></b> выводит еще куски текста которые стоят в заголовке в <b></b>.


    Не понял, что с этим делать.
     
  4. APXOH

    APXOH Создатель

    Регистр.:
    16 янв 2013
    Сообщения:
    36
    Симпатии:
    6
    Вам предлагают дополнительно обработать парсеный текст перед подачей на preg_match чтобы убрать лишние теги которые мешают
     
    4ksner нравится это.
  5. 4ksner

    4ksner Постоялец

    Регистр.:
    6 июн 2012
    Сообщения:
    142
    Симпатии:
    60
    lefoyer, огромное спасибо!
    В итоге сделал вот так:
    PHP:
    $data preg_replace('/\s\s+/'''$data); // Убираем лишние пробелы между </b> и <p>
    $data str_ireplace('<b>'""$data); // Удаляем тег <b>
    $data str_ireplace('</b>'""$data); // Удаляем тег </b>
    $data strip_tags($data'<p><b><a>'); // Удаляем теги <img /> которые попадаются между </b> и <p>
    preg_match_all('|<a href="\/([^<]+)\/detail\/(.+).html">(.+)<p>|Uim'$data$pages);
    P.S. Тему можно закрывать