To reduce a string but without removing formatting, try my function here.
<?php
//An example
print html_substr("my <u>markeup<u> text", 0, 10 );
//Output: my <u>markeup<u>
?>
<?php
/**
* This function extracts the non-tags string and returns a correctly formatted string
* It can handle all html entities e.g. &, ", etc..
*
* @param string $s
* @param integer $srt
* @param integer $len
* @param bool/integer Strict if this is defined, then the last word will be complete. If this is set to 2 then the last sentence will be completed.
* @param string A string to suffix the value, only if it has been chopped.
*/
function html_substr( $s, $srt, $len = NULL, $strict=false, $suffix = NULL )
{
if ( is_null($len) ){ $len = strlen( $s ); }
$f = 'static $strlen=0;
if ( $strlen >= ' . $len . ' ) { return "><"; }
$html_str = html_entity_decode( $a[1] );
$subsrt = max(0, ('.$srt.'-$strlen));
$sublen = ' . ( empty($strict)? '(' . $len . '-$strlen)' : 'max(@strpos( $html_str, "' . ($strict===2?'.':' ') . '", (' . $len . ' - $strlen + $subsrt - 1 )), ' . $len . ' - $strlen)' ) . ';
$new_str = substr( $html_str, $subsrt,$sublen);
$strlen += $new_str_len = strlen( $new_str );
$suffix = ' . (!empty( $suffix ) ? '($new_str_len===$sublen?"'.$suffix.'":"")' : '""' ) . ';
return ">" . htmlentities($new_str, ENT_QUOTES, "UTF-8") . "$suffix<";';
return preg_replace( array( "#<[^/][^>]+>(?R)*</[^>]+>#", "#(<(b|h)r\s?/?>){2,}$#is"), "", trim( rtrim( ltrim( preg_replace_callback( "#>([^<]+)<#", create_function(
'$a',
$f
), ">$s<" ), ">"), "<" ) ) );
}
?>
More tests
$s = <<<EOF Crop at 10 <a href='path'>path</a> path <ul><li><ul><li>First Nested Crop at line 50 <ul><li>Deep nested. Crop at line 80</li></ul></li></ul></li></ul> Crop at 90 EOF; print "\n" . html_substr($s, 0, 10 ); //Crop at 10 print "\n" . html_substr($s, 0, 50 ); //Crop at 10 <a href='path'>path</a> path <ul><li><ul><li>First Nested Crop at line 50</li></ul></li></ul> print "\n" . html_substr($s, 0, 80 ); //Crop at 10 <a href='path'>path</a> path <ul><li><ul><li>First Nested Crop at line 50 <ul><li>Deep nested. Crop at line 80</li></ul></li></ul></li></ul> print "\n" . html_substr($s, 0, 90 ); //Crop at 10 <a href='path'>path</a> path <ul><li><ul><li>First Nested Crop at line 50 <ul><li>Deep nested. Crop at line 80</li></ul></li></ul></li></ul> //Crop at 90 $s = <<<EOF 1<a href='path'>2</a>34<ul><li><ul><li>5<ul><li>6</li></ul></li></ul></li></ul>789 EOF; print "\n" . html_substr($s, 0, 1 ); //1 print "\n" . html_substr($s, 0, 3 ); //1<a href='path'>2</a>3 print "\n" . html_substr($s, 0, 6 ); //1<a href='path'>2</a>34<ul><li><ul><li>5<ul><li>6</li></ul></li></ul></li></ul> print "\n" . html_substr($s, 0, 7 ); //<a href='path'>2</a>34<ul><li><ul><li>5<ul><li>6</li></ul></li></ul></li></ul>7
Comments
mihai
life saving function :)
Created 22/01/09
drew
Thankyou very much
Created 20/02/09
If Image is outside the given character count
This function is awesome. The only suggestion that comes to mind is say that an image referance starts at character 190. I have set the html_substr to stop at 100 characters; however the image that starts at the 190 mark will still be output.
Created 20/08/10
Thankyou
Good function! helped me a lot!
Created 09/09/10
Works well - Thanks
Just implemented this function, saved me sometime, thanks for publishing it
Created 22/08/11
Thank you very much
nice function
Created 21/09/11
Excellent
Great function, though it kinda reads like it's from the Obfuscated C Contest. ;)
My suggestion for international users would be to omit the third parameter of the html_entities() call as that messes up special chars even if they go in as HTML encod...
Created 13/10/11
