Очевидно, что прямая резка строки не подходит для вашего второго изображения:
...
<figure>
<img class="aligncenter" src="http://brickhut.files.wordpress.com/2011/05/theempirestrikesback1.jpg" alt="" width="540" height="800" />
<figcaption></figcaption>
</figure>
Вырезание после изображения оставит незакрытые элементы:
...
<figure>
<img class="aligncenter" src="http://brickhut.files.wordpress.com/2011/05/theempirestrikesback1.jpg" alt="" width="540" height="800" />
Что может разрушить рендеринг страницы внутри браузера. И не играет роли, если вы используете здесь preg_match
с регулярным выражением или какие-то строковые функции.
Вам нужен синтаксический анализатор DOM, такой как DOMDocument
, способный обрабатывать HTML:
Учитывая пример кода HTML, который похож на ваш вопрос:
$html = <<<HTML
dolor sit amet, consectetuer adipiscing elit. <img src="http://example.com/img-a.jpg"> Aenean commodo
ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus.
<figure>
<img src="http://example.com/img-b.jpg">
<figcaption>Figure Caption</figcaption>
</figure>
Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut.
HTML;
Теперь вы можете использовать класс DOMDocument
для загрузки фрагмента HTML внутри тега <body>
, потому что это все ваше тело html для манипуляции. Поскольку вы используете нестандартные теги HTML (<figure>
и <figcaption>
), вам следует отключить предупреждения о них при загрузке строки с помощью libxml_use_internal_errors
:
$doc = new DOMDocument();
libxml_use_internal_errors(1);
$doc->loadHTML(sprintf('<body>%s</body>', $html));
Это базовая настройка парсера DOM, теперь ваш HTML находится внутри парсера. Теперь самое интересное. Вы хотите создать выдержку до второго изображения документа. Это означает, что все, что находится после этого элемента, должно быть удалено. Звучит так же просто, как обрезать строку, которая, как мы знаем, не работает, но на этот раз парсер DOM сделает всю работу за нас.
Вам нужно только получить все узлы (<tag>
, Text, <!-- comments -->
, ...) и удалить их. Все узлы после второго тега <img>
в (следующем порядке документа). Такие вещи можно выразить с помощью XPath:
/descendant::img[position()=2]/following::node()
Парсер PHP DOM поставляется с XPath, поэтому давайте сделаем это:
$xp = new DOMXPath($doc);
$delete = $xp->query('/descendant::img[position()=2]/following::node()');
foreach ($delete as $node)
{
$node->parentNode->removeChild($node);
}
Осталось только получить (образцовый вывод) оставшийся отрывок. Как мы знаем, все это находится внутри тега <body>
:
foreach ($doc->getElementsByTagName('body')->item(0)->childNodes as $child)
{
echo $doc->saveHTML($child);
}
Что даст вам следующее:
dolor sit amet, consectetuer adipiscing elit. <img src="http://example.com/img-a.jpg"> Aenean commodo
ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes,
nascetur ridiculus mus.
<figure><img src="http://example.com/img-b.jpg"></figure>
Как показывает этот пример, тег <figure>
теперь правильно закрыт.
Аналогичный сценарий заключается в создании отрывка после определенной длины текста или количества слов: Перенос слов/вырезание текста в строке HTML
person
hakre
schedule
24.02.2012