0

I'm looking to replace the last occurrence of P tag in a string.

$bodytext = preg_replace(strrev("/<p>/"),strrev('<p class="last">'),strrev($bodytext),1);
$bodytext = strrev($bodytext);

This works, but can it be done without using strrev? Is there a regex solution?

Something like :

$bodytext = preg_replace('/<p>.?$/', '<p class="last">', $bodytext);

Any help would be greatly appreciated.

My shortened version:

$dom = new DOMDocument();
$dom->loadHTML($bodytext);
$paragraphs = $dom->getElementsByTagName('p');
$last_p = $paragraphs->item($paragraphs->length - 1);
$last_p->setAttribute("class", "last");
$bodytext = $dom->saveHTML();
Brian Smith
  • 1,443
  • 5
  • 18
  • 24
  • 4
    [Don't use regexes for parsing HTML](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454). Use the DOM instead, Look into [DOMDocument](http://www.php.net/manual/en/book.dom.php). – John Conde Mar 23 '14 at 02:56
  • If you're doing that so that you can style the last `p`, you should consider using `p:last` instead. – pguardiario Mar 23 '14 at 04:15
  • That was the first thing I looked at, but I would still like to support IE 7 & 8. – Brian Smith Mar 23 '14 at 17:04

2 Answers2

1

Some people will complain that DOMDocument is more verbose for parsing HTML then a regex. But verbosity is okay if it means using the right tool for the job.

$previous_value = libxml_use_internal_errors(TRUE);
$string = '<p>hi, mom</p><p>bye, mom</p>';
$dom = new DOMDocument();
$dom->loadHTML($string);
$paragraphs = $dom->getElementsByTagName('p');
$last_p = $paragraphs->item($paragraphs->length - 1);
$last_p->setAttribute("class", "last");
$new_string = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML()));
libxml_clear_errors();
libxml_use_internal_errors($previous_value);

echo htmlentities($new_string);
// <p>hi, mom</p><p class="last">bye, mom</p>

See it in action

John Conde
  • 217,595
  • 99
  • 455
  • 496
0

How about using simple html dom?

require_once('simple_html_dom.php');

$string = '<p>hi, mom</p><p>bye, mom</p>';
$doc = str_get_html($string);
$doc->find('p', -1)->class = 'last';
echo $doc;
// <p>hi, mom</p><p class="last">bye, mom</p>
pguardiario
  • 53,827
  • 19
  • 119
  • 159