Как получить строку из HTML с помощью регулярных выражений? - PullRequest
2 голосов
/ 21 июля 2010

Я пытаюсь разобрать блок со страницы HTML, поэтому я пытаюсь preg_match этот блок с php

if( preg_match('<\/div>(.*?)<div class="adsdiv">', $data, $t)) 

но не работает

</div>

blablabla

blablabla

blablabla

<div class="adsdiv">

я хочу только grep blablabla blablabla слов любая помощь

Ответы [ 4 ]

1 голос
/ 21 июля 2010

Regex не является правильным инструментом для этого .Вот как это сделать с DOM

$html = <<< HTML
<div class="parent">
    <div>
        <p>previous div<p>
    </div>
    blablabla
    blablabla
    blablabla
    <div class="adsdiv">
        <p>other content</p>
    </div>
</div>
HTML;

Содержимое в документе HTML - это TextNodes.Теги - это ElementNodes.Ваш TextNode с содержимым blablabla должен иметь родительский узел.Для извлечения значения TextNode, мы будем предполагать, что вы хотите, чтобы все TextNode ParentNode атрибута div с class имели значение adsdiv

$dom = new DOMDocument;
$dom->loadHTML($html);
$xPath = new DOMXPath($dom);
$nodes = $xPath->query('//div[@class="adsdiv"]');
foreach($nodes as $node) {
    foreach($node->parentNode->childNodes as $child) {
        if($child instanceof DOMText) {
            echo $child->nodeValue;
        }
    };
}

Да, это не какой-то фантик, ноэто также намного меньше головной боли и дает вам полный контроль над документом HTML.Используя возможности запроса XPath, мы могли бы сократить это до

$nodes = $xPath->query('//div[@class="adsdiv"]/../text()');
foreach($nodes as $node) {
    echo $node->nodeValue;
}

Я оставил его намеренно многословным, чтобы проиллюстрировать, как использовать DOM.

1 голос
/ 21 июля 2010

Помимо того, что было сказано выше, также добавьте модификатор /s, чтобы . соответствовал символам новой строки.(edit: как любезно отметил Алан, [^<]+ будет соответствовать символам новой строки в любом случае)

Я также всегда использую /U, так как в этих случаях обычно требуется минимальное соответствие по умолчанию.(будет быстрее).И /i, поскольку люди говорят <div>, <DIV> или даже <Div> ...

if (preg_match('/<\/div>([^<]+)<div class="adsdiv">/Usi', $data, $match))
{
    echo "Found: ".$match[1]."<br>";
} else {
    echo "Not found<br>";
}

edit , сделали его немного более явным!

0 голосов
/ 21 июля 2010

Из Руководства PHP :

s (PCRE_DOTALL) - Если этот модификатор установлен, метасимвол точки в шаблон соответствует всем персонажам, в том числе и новые строки. Без этого, новые строки исключены. Этот модификатор эквивалентно модификатору Perl's / s. отрицательный класс, такой как [^ a] всегда соответствует символу новой строки, независимо от настройки этого Модификатор.

Итак, должно работать следующее:

if (preg_match('~<\/div>(.*?)<div class="adsdiv">~s', $data, $t))

~ здесь для ограничения регулярного выражения.

0 голосов
/ 21 июля 2010

Вы должны разделить свое регулярное выражение; используйте /<\/div>(.*?)<div class="adsdiv">/ вместо.

...