Truncate Long Titles to the Nearest Whole Word Using PHP strrpos

I ran into what must be a common problem while coding a WordPress plugin the other day, and I had a surprisingly difficult time finding a satisfactory answer: Is there a way to truncate long titles to the nearest whole word, without cutting off any part of a word?

I’ll give you an example. Suppose I want to put a list of recent articles in the sidebar of my site. Suppose further that one of the articles has the following headline (this is an actual title I found on the Web):

Social Networks and Recidivism of Deinstitutionalized Mental Patients

Obviously that is far too long to fit into a typical sidebar, so we’ll have to truncate it. Suppose I decide that 35 is the maximum number of characters that can fit in my sidebar. We can easily truncate any string to a specified length using the substr function:

echo substr( $title, 0, 35 );

If we run that on the above title, it prints the following string:

Social Networks and Recidivism of D

Simple enough — but it does look a little odd to have that ‘D’ hanging by itself at the end of the string. It would be much better if we could truncate to the nearest whole word. I did a little searching and found some sample code which purports to do that:

echo substr( $title, 0, strpos($title, ' ', 35) );

The strpos (string position) function finds the position of the first occurrence of a character in a string. Here, we are using it to find the position of the first space after the maximum length we have set. Then, the string is truncated to that position.

If the next whole word has an average length of 5-6 characters like most English words, that might work just fine. But in this (admittedly contrived) example, the next whole word is a whopping 18 characters longer than our limit:

Social Networks and Recidivism of Deinstitutionalized

Suppose we want to guarantee that the truncated title will never be longer that 35 characters? What we really need is a way to find the position of the first space before the limit. Fortunately, the strrpos (string reverse position) function allows us to do just that:

echo substr( $title, 0, strrpos( substr( $title, 0, 35), ' ' ) );

What exactly is this doing? The strrpos function is like strpos, except that it finds the position of the last occurrence of a character in a string (notice that one extra ‘r’ in the function name, it makes a big difference!). Working from the nested substr outward: we first truncate the title to our maximum length. Then, we feed the truncated title into strrpos, and let it find the position of the last space. Finally, we truncate the title again, using the position that was returned by strrpos. The end result is exactly what we wanted:

Social Networks and Recidivism of

And there you have it — a reliable method of truncating any string to the nearest whole word, while staying under the maximum string length. I am using exactly this method to truncate the long post titles under “More From the Blog” below.

Addendum

After I finished writing all of this up, I discovered there is another way to do it: you can use the explode function, with a space as the delimiter, to break the string up into words, then reassemble them using a loop, up to the maximum string length. I’m not sure which method is faster from an execution standpoint; I still feel the solution I presented earlier is cleaner and more compact. Do you know of an even better way to do it? Please sound off below.

More From the Blog

Comments

  1. Nathan Buchanan says:

    This is great!
    The only thing is, How do I implement this? Would you be able to give a brief description of how to insert this code into the actual pages please?

  2. Peter from Hungary says:

    Thanks so much for this solution! This is exactly, what I was looking for. Thx! ;)

  3. richard says:

    thank you!
    really useful, beautifully simple. it really helped me.

  4. RagingRaven says:

    I found that there are 2 situations where you might need an addition to your code:

    1 if you don’t know how long your string is beforehand, for instance if you use this in a function, you will need to check if the length of the given string is shorter than the truncate length, because if it is it will truncate off the last word even though it could show the entire sentence.

    2. What if there are no spaces in the given string or the spaces are all after the given truncate length? You will have to truncate the sentence at the given length even though this will cut off at half a word in this example, but it’s still better than not truncating.

    For those interested I made a function using the given code but with the above additions:

    function truncateStr($input, $length)
    {
    //only truncate if input is actually longer than $length
    if(strlen($input) > $length)
    {
    //check if there are any spaces at all and if the last one is within the given length if so truncate at space else truncate at length.
    if(strrchr($input, ” “) && strrchr($input, ” “) < $length)
    {
    return substr( $input, 0, strrpos( substr( $input, 0, $length), ' ' ) )."…";
    }
    else
    {
    return substr( $input, 0, $length )."…";
    }
    }
    else
    {
    return $input;
    }
    }

  5. Max Stern Dahl says:

    Hi,

    And another way to do this, which accounts for short, long, no space strings, and which is multibyte safe is:

    function trimStringToFullWord($length, $string) {
    if (mb_strlen($string) <= $length) {
    $string = $string; //do nothing
    }
    else {
    $string = preg_replace('/\s+?(\S+)?$/u', '', mb_substr($string, 0, $length));
    }
    return $string;
    }

  6. ambrosite says:

    @Max Thanks for your contribution. I was never big on regular expressions, but I’ll take your word for it that it works!

Comments are closed.