Regex и PHP для извлечения содержимого между тегами с несколькими переносами строк - PullRequest
0 голосов
/ 10 июня 2010

Как извлечь содержимое между тегами с несколькими переносами строк?

Я новичок в регулярных выражениях, который хотел бы знать, как обрабатывать неизвестные числа разрыва строки, чтобы соответствовать моему запросу.

Задача: извлечь содержимое между <div class="test"> и первым закрывающим тегом </div>.

Оригинальный источник:

<div class="test">optional text<br/>
content<br/>
<br/>
content<br/>
...
content<br/><a href="/url/">Hyperlink</a></div></div></div>

Я разработал следующее регулярное выражение,

/<div class=\"test\">(.*?)<br\/>(.*?)<\/div>/

Интересно, как сопоставить несколько разрывов строк с помощью регулярных выражений.

Для нас есть DOM, но я не знаком с этим.

Ответы [ 2 ]

2 голосов
/ 10 июня 2010

Вы не должны анализировать (x) html с регулярными выражениями. Используйте DOM.

Я новичок в xpath, но такой должен работать:

//div[@class='test']

Это выбирает все div с классом 'test'. Вам нужно будет загрузить html в объект DOMDocument, затем создать связанный с ним объект DOMXpath и вызвать его метод execute(), чтобы получить результаты. Он вернет объект DOMNodeList.
Конечный код выглядит примерно так:

$domd = new DOMDocument();
$domd->loadHTML($your_html_code);
$domx = new DOMXPath($domd);
$items = $domx->execute("//div[@class='test']");

После этого ваш div находится в $items->item(0).

Это непроверенный код, но если я правильно помню, он должен работать.

Обновление , забыл, что вам нужен контент.

Если вам нужен текст text (без тегов), вы можете просто позвонить $items->item(0)->textContent. Если вам также нужны теги, вот эквивалент innerHTML javascript для PHP DOM:

function innerHTML($node){
  $doc = new DOMDocument();
  foreach ($node->childNodes as $child)
    $doc->appendChild($doc->importNode($child, true));

  return $doc->saveHTML();
}

Вызовите его с $items->item(0) в качестве параметра.

0 голосов
/ 10 июня 2010

Вы можете использовать preg_match_all('/<div class="test">(.*?)<\/div>/si', $html, $matches);.Но помните, что это будет соответствовать первому закрытию </div> в HTML.То есть.если HTML выглядит как <div class="test">...aaa...<div>...bbb...</div>...ccc...</div>, то вы получите ...aaa...<div>...bbb... как результат в $ match ...

Так что в итоге использование парсера DOM действительно будет лучшим решением.

...