Помогите с preg_match_all

4ksner

Постоялец
Регистрация
6 Июн 2012
Сообщения
149
Реакции
62
Пишу парсер выдачи поиска с одного сайта.
Выдача:
Код:
 <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>?
 
Вообще удивительно как это работает...
Попробуй заэкранировать (поставить слеши "\") перед теми символами, которые используются в регулярках как мета символы Для просмотра ссылки Войди или Зарегистрируйся Потому как сейчас регулярка если и работает, то не так как ты предполагаешь...
например вот эта часть выражения
Код:
[/B].
- будет искать символ "/" или символ "B" и после него еще один любой символ, кроме перевода строки, что аж никак не соответствует закрывающему bold BB-коду + точка, который в регулярке будет выглядеть как-то так
Код:
\[/B\]\.
 
Исходник:

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>, то он все-равно режет заголовок.

echo $a->first_child() . '<br>';
заменить на
echo $a->innertext.'<br>';
При этом мне выводится полная структура между тегами a:

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

А preg_match_all и не мог заработать, у Вас в примере сейчас нет никаких и как было в предыдущих примерах.
preg_match_all('|<a href="\/news\/detail\/(.+).html"><b>(.+)<\/b><\/a>|Uim', $data, $pages);
Ни чего не находит, как я понимаю из-за того, что после закрывающего тега b, есть еще p:

<a href="/news/detail/NEWS_ID.html"><b>TITLE<b>TITLE</b>TITLE</b>


<p>TEXT</p></a>



Если надо внутри b (синтаксис jquery)
foreach($html->find('div.search-page') as $div) {
foreach($div->find('a[href^=/news/detail/] > b') as $b) {echo $b->innertext.'<br>';
}
}
Помимо заголовков без <b></b> выводит еще куски текста которые стоят в заголовке в <b></b>.


А поскольку как я понял Вам надо убрать все <b> и </b> теги делаем
$text = str_ireplace('<b>', "", $text);
$text = str_ireplace('</b>', "", $text);
Тоже можно и с остальными тегами.
Не понял, что с этим делать.
 
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. Тему можно закрывать
 
Назад
Сверху