views:

401

answers:

5

Here is the question: How would your trim a block of text to the nearest word when a certain amount of characters have past. I'm not trying to limit a certain number words or letters, but limit the letters and cut it off at the nearest word.

Say I had two strings:

"This is a block of text, blah blah blah"
"this is another block of txt 2 work with"

Say I wanted to limit it to 27 characters, the first line would end at "blah" and the second on would end at "txt" even though the character limits are reached within those words.

Is there any clean solution to this problem?

A: 

Wouldn't it be simpler to concat the strings using a place holder (i.e.: ###PLACEHOLDER###), count the chars of the string minus your place holder, trim it to the right length with substr and then explode by placeholder?

Andrei Serdeliuc
+2  A: 

See the wordwrap function.

I would probably do something like:

function wrap($string) {
  $wstring = explode("\n", wordwrap($string, 27, "\n") );
  return $wstring[0];
}

(If your strings already span across severeal lines, use other char - or pattern - for the split other than "\n")

jcinacio
chr(10) is a better solution than '\n' I believe.
Andrei Serdeliuc
@Apikot - i think anything would work here, as long as it's not present in the string - even something like "[:CUT:]", for example.
jcinacio
A: 

I think this should do the trick:

function trimToWord($string, $length, $delimiter = '...')
{
    $string        = str_replace("\n","",$string);
    $string        = str_replace("\r","",$string);
    $string        = strip_tags($string);
    $currentLength = strlen($string);

    if($currentLength > $length)
    {
        preg_match('/(.{' . $length . '}.*?)\b/', $string, $matches);

        return rtrim($matches[1]) . $delimiter;
    }
    else 
    {
        return $string;
    }
}
Kieran Hall
A: 

You can use a little-known modifier to str_word_count to help do this. If you pass the parameter '2', it returns an array of where the word position are.

The following is a simple way of using this, but it might be possible to do it more efficiently:

$str = 'This is a string with a few words in';
$limit = 20;
$ending = $limit;

$words = str_word_count($str, 2);

foreach($words as $pos=>$word) {
    if($pos+strlen($word)<$limit) {
        $ending=$pos+strlen($word);
    }
    else{
        break;
    }
}

echo substr($str, 0, $ending);
// outputs 'this is a string'
Ciaran McNulty
+1  A: 

I wrote a max-string-length function that does just this and is very clean.

aleemb
Why not remove the else block and return $text outside the if block?
Josh Smeaton
Good point. Refactored to remove the if block altogether.
aleemb