Trim text to 340 chars [duplicate]
Asked Answered
A

9

15

I'm pulling blog posts from a DB. I want to trim the text to a max length of 340 characters.

If the blog post is over 340 characters I want to trim the text to the last full word and add '...' on the end.

E.g.

NOT: In the begin....

BUT: In the ...
Anagram answered 20/1, 2010 at 20:21 Comment(1)
What would you like to do if the user enters a single word with length 341 characters (with no spaces at all in the post)?Diazo
D
18

The other answers show you how you can make the text roughly 340 characters. If that's fine for you, then use one of the other answers.

But if you want a very strict maximum of 340 characters, the other answers won't work. You need to remember that adding the '...' can increase the length of the string and you need to take account of that.

$max_length = 340;

if (strlen($s) > $max_length)
{
    $offset = ($max_length - 3) - strlen($s);
    $s = substr($s, 0, strrpos($s, ' ', $offset)) . '...';
}

Note also that here I'm using the overload of strrpos that takes an offset to start searching directly from the correct location in the string, rather than first shortening the string.

See it working online: ideone

Diazo answered 20/1, 2010 at 20:30 Comment(4)
wouldn't doing $.='...' be easier instead of the last step ?Stephen
@silkAdmin: Thanks for your comment. I've made some improvements to my answer.Diazo
Cool, pretty old thread but i am sure it'll still be useful for plenty of people!Stephen
It should be noted that this produces nothing but "..." if there's no spaces in the textAcree
A
29

It seems like you would want to first trim the text down to 340 characters exactly, then find the location of the last ' ' in the string and trim down to that amount. Like this:

$string = substr($string, 0, 340);
$string = substr($string, 0, strrpos($string, ' ')) . " ...";
Avivah answered 20/1, 2010 at 20:26 Comment(1)
Needs some polish (check if string needs to get shortened, etc) but short and sweet.Killebrew
D
18

The other answers show you how you can make the text roughly 340 characters. If that's fine for you, then use one of the other answers.

But if you want a very strict maximum of 340 characters, the other answers won't work. You need to remember that adding the '...' can increase the length of the string and you need to take account of that.

$max_length = 340;

if (strlen($s) > $max_length)
{
    $offset = ($max_length - 3) - strlen($s);
    $s = substr($s, 0, strrpos($s, ' ', $offset)) . '...';
}

Note also that here I'm using the overload of strrpos that takes an offset to start searching directly from the correct location in the string, rather than first shortening the string.

See it working online: ideone

Diazo answered 20/1, 2010 at 20:30 Comment(4)
wouldn't doing $.='...' be easier instead of the last step ?Stephen
@silkAdmin: Thanks for your comment. I've made some improvements to my answer.Diazo
Cool, pretty old thread but i am sure it'll still be useful for plenty of people!Stephen
It should be noted that this produces nothing but "..." if there's no spaces in the textAcree
B
18

If you have the mbstring extension enabled (which is on most servers nowadays), you can use the mb_strimwidth function.

echo mb_strimwidth($string, 0, 340, '...');
Blenny answered 7/6, 2014 at 5:31 Comment(0)
B
7

try:

preg_match('/^.{0,340}(?:.*?)\b/siu', $text, $matches);
echo $matches[0] . '...';
Biannulate answered 20/1, 2010 at 20:26 Comment(1)
By default, the . does not match line breaks. So when there are line breaks before the 340th character, it will not work. Adding a s modifier in the end will do the trick.Balthazar
P
2

I put the answer of John Conde in a method:

function softTrim($text, $count, $wrapText='...'){

    if(strlen($text)>$count){
        preg_match('/^.{0,' . $count . '}(?:.*?)\b/siu', $text, $matches);
        $text = $matches[0];
    }else{
        $wrapText = '';
    }
    return $text . $wrapText;
}

Examples:

echo softTrim("Lorem Ipsum is simply dummy text", 10);
/* Output: Lorem Ipsum... */

echo softTrim("Lorem Ipsum is simply dummy text", 33);
/* Output: Lorem Ipsum is simply dummy text */

echo softTrim("LoremIpsumissimplydummytext", 10);
/* Output: LoremIpsumissimplydummytext... */
Pinchas answered 15/2, 2013 at 14:22 Comment(0)
M
1

you can try using functions that comes with PHP , such as wordwrap

print wordwrap($text,340) . "...";
Matthiew answered 21/1, 2010 at 1:22 Comment(0)
R
0

function trim_characters( $text, $length = 340 ) {

$length = (int) $length;
$text = trim( strip_tags( $text ) );

if ( strlen( $text ) > $length ) {
    $text = substr( $text, 0, $length + 1 );
    $words = preg_split( "/[\s]| /", $text, -1, PREG_SPLIT_NO_EMPTY );
    preg_match( "/[\s]| /", $text, $lastchar, 0, $length );
    if ( empty( $lastchar ) )
        array_pop( $words );

    $text = implode( ' ', $words ); 
}

return $text;

}

Use this function trim_characters() to trims a string of words to a specified number of characters, gracefully stopping at white spaces. I think this is helpful to you.

Robi answered 1/11, 2012 at 11:47 Comment(0)
H
0

Why this way?

  • I like the regex solution over substring, to catch any other than whitespace word breaks (interpunction etc.)
  • John Condoe's solution is not perfectly correct, since it trim text to 340 characters and then finish the last word (so will often be longer than desired)

Actual regex solution is very simple:

/^(.{0,339}\w\b)/su

Full method in PHP could look like this:

function trim_length($text, $maxLength, $trimIndicator = '...')
{
        if(strlen($text) > $maxLength) {

            $shownLength = $maxLength - strlen($trimIndicator);

            if ($shownLength < 1) {

                throw new \InvalidArgumentException('Second argument for ' . __METHOD__ . '() is too small.');
            }

            preg_match('/^(.{0,' . ($shownLength - 1) . '}\w\b)/su', $text, $matches);                               

            return (isset($matches[1]) ? $matches[1] : substr($text, 0, $shownLength)) . $trimIndicator ;
        }

        return $text;
}

More explanation:

  • $shownLength is to keep very strict limit (like Mark Byers mentioned)
  • Exception is thrown in case given length was too small
  • \w\b part is to avoid whitespace or interpunction at the end (see 1 below)
  • In case first word would be longer than desired max length, that word will be brutally cut

  1. Despite the fact that in question result In the ... is described as desired, I feel In the... is more smooth (also don't like In the,... etc.)
Hemialgia answered 5/2, 2016 at 14:2 Comment(0)
R
0

Simplest solution

$text_to_be_trim= "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry standard.";
if(strlen($text_to_be_trim) > 20)   
    $text_to_be_trim= substr($text_to_be_trim,0,20).'....';

For multi-byte text

$stringText= "UTIL CONTROL DISTRIBUCION AMARRE CIGÜEÑAL";
$string_encoding = 'utf8';
$s_trunc =  mb_substr($stringText, 0, 37, $string_encoding);
echo $s_trunc;
Ressieressler answered 23/5, 2017 at 11:38 Comment(4)
This one may fail when you meet an special char. Just happened to me with ü. If you chop right there, it fails. If you go one character further, it works. So, Mark Byers answer is my preferred. Works perfectly.Internecine
Could you please share the text which is to be trimmed? So that i can check my solution..Ressieressler
Sure. Try this and cut in in the Ü: "UTIL CONTROL DISTRIBUCION AMARRE CIGÜEÑAL". Letter 40 for me.Internecine
Thanks for the string & If you want trim multi-byte text please use mb_substr and i'm updating my answer for special character alsoRessieressler

© 2022 - 2024 — McMap. All rights reserved.