0

I'm trying to take a string and cut it off at a certain point (basically to provide a preview of the selected text) but there may be images or similar content inside (using BBCode for this) and I was wondering if there was a simple way to do this in PHP.

Example:

$content = "blah blah blah such and such [img]imagehere[/img] blah blah";
$preview=unknownfunction($content); //cuts off at approx. 40 chars
//do not want this:
$preview="blah blah blah such and such [img]image";//this is bad because half of image is gone
//want this:
$preview="blah blah blah such and such [img]imagehere[/img]"; //this is good because even though it reached 40 chars, it let it finish the image.

Is there a simple way to do this? Or at the very least, I could remove all tags from the preview element, but I'd still like this function to not cut off any words.

muttley91
  • 12,278
  • 33
  • 106
  • 160
  • First remove the "bbcoded" content, then count the remaining words and split by that (MyBB forum, for example, worked like that last time I checked) – Damien Pirsy Feb 28 '12 at 16:38
  • I feel like I'm answering this often. http://stackoverflow.com/a/9202571/383402 and the other answers there. – Borealid Feb 28 '12 at 16:40
  • If you can get a list of BB tags you can split the string using preg_match_all and make the calculation thereafter. Otherwise you can use a regular expression using the `[``]` characters but I'm not sure how it parses the unrecognized tags. – inhan Feb 28 '12 at 16:44
  • is there any good way to strip all the BB tags out? – muttley91 Feb 28 '12 at 16:45

4 Answers4

1

check this out :

$ php -a

php > $maxLen = 5;
php > $x = 'blah blah blah such and such [img]imagehere[/img] blah blah';
php > echo substr(preg_replace("/\[\w+\].*/", "", $x), 0, $maxLen);
blah 
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
1

Heres a function that uses regex

<?php 
function neat_trim($str, $n, $delim='') {
    $len = strlen($str);
    if ($len > $n) {
        preg_match('/(.{'.$n.'}.*? )\b/', $str, $matches);
        return @rtrim($matches[1]) . $delim;
    }else {
        return $str;
    }
}


$content = "blah blah blah such and such [img]imagehere[/img] blah blah";
echo neat_trim($content, 40);
//blah blah blah such and such [img]imagehere[/img] 
?>
Lawrence Cherone
  • 46,049
  • 7
  • 62
  • 106
  • For some reason this showed no text whatsoever. I'm going to keep working with it, though, to see if it ends up working. – muttley91 Feb 28 '12 at 17:07
1

A problem you'll have is that you need to come up with some rules. If the string is

$str = '[img]..[img] some text here... ';

Then will you ignore the image and just extract the text? If so, you may want to use some regular expressions to strip all the BB code out of a copy of the string. But then it will consider text on both sides in an instance such as

$str = 'txt txt [img]....[/img] txtxtxt ; // will become $copystr = 'txttxt  txttxttxt';

You can get a 'marker' with strpos of the first occurrence of '[', '[img]', or an array of the elements you dont want to allow. Then cycle through those, and if they're less than your desired 'preview' length, then use that position++ as your length.

<?php
function str_preview($str,$len){
   $occ = strpos('[',$str);
   $occ = ($occ > 40) ? 40 : $occ;
   return substr($str,0,++$occ);
}
?>

something like that would work if you want to go up to the first '['. If you want to ignore [B] (or others) and allow them to be applied, then you would want to write a more complex filtering pattern that allows that. Or - if you want to make sure it doesn't cut off in the middle of a word, you have to consider the strpos(' '..) using offset to change the length how you need it. There won't be a magical 1 liner to handle it.

S Morgan
  • 191
  • 1
  • 4
0

One solution I found was the following

<?php
    function getIntro($content)
    {
        if(strlen($content) > 350)
        {
            $rough_short_par = substr($content, 0, 350); //chop it off at 350
            $last_space_pos = strrpos($rough_short_par, " "); //search from end: http://uk.php.net/manual/en/function.strrpos.php
            $clean_short_par = substr($rough_short_par, 0, $last_space_pos);
            $clean_sentence = $clean_short_par . "...";
            return $clean_sentence; 
        }
        else
        {
            return $content;
        }
    }
?>

It works to prevent cutting off words, but it could still cut off tags. What I might do for this is prevent images from being posted in the preview text, and have a preview image displayed which I already have stored. This will prevent cutting off images.

muttley91
  • 12,278
  • 33
  • 106
  • 160