How can I truncate a string after 20 words in PHP?
-
1You might find [`s($str)->words(20)`](https://github.com/delight-im/PHP-Str/blob/8fd0c608d5496d43adaa899642c1cce047e076dc/src/Str.php#L363) helpful, as found in [this standalone library](https://github.com/delight-im/PHP-Str). – caw Jul 27 '16 at 00:42
29 Answers
function limit_text($text, $limit) {
if (str_word_count($text, 0) > $limit) {
$words = str_word_count($text, 2);
$pos = array_keys($words);
$text = substr($text, 0, $pos[$limit]) . '...';
}
return $text;
}
echo limit_text('Hello here is a long sentence that will be truncated by the', 5);
Outputs:
Hello here is a long ...
-
6This function confuses character count and word count when using $limit in one case as a word selector of the array $pos and in another by determining if the string is long enough. – Aaron Jul 06 '10 at 19:21
-
In the example provided, passing in a value of 5 ensures that the function will act on any word of length greater than 5 characters, so had the test case been "Hello here", the function fails and returns only "..." – Aaron Jul 06 '10 at 19:42
-
-
2`str_word_count` instead of `strlen` should do the trick :) so replace `strlen($text)` with `str_word_count($text,0)` – Val Feb 21 '12 at 15:26
-
1Note on str_word_count($text, 2) from the docs `For the purpose of this function, 'word' is defined as a locale dependent string containing alphabetic characters, which also may contain, but not start with "'" and "-" characters.` you can specify additional characters in the third param, or just use `preg_split('/[\s]+/' $text);` to split by white space. – Chris Hanson Sep 23 '13 at 21:19
-
1its working for english, not for Arabic language, i assume not for UTF-8? or am i missing something? – Omar N Shamali Jun 26 '18 at 14:43
Change the number 3 to the number 20 below to get the first 20 words, or pass it as parameter. The following demonstrates how to get the first 3 words: (so change the 3 to 20 to change the default value):
function first3words($s, $limit=3) {
return preg_replace('/((\w+\W*){'.($limit-1).'}(\w+))(.*)/', '${1}', $s);
}
var_dump(first3words("hello yes, world wah ha ha")); # => "hello yes, world"
var_dump(first3words("hello yes,world wah ha ha")); # => "hello yes,world"
var_dump(first3words("hello yes world wah ha ha")); # => "hello yes world"
var_dump(first3words("hello yes world")); # => "hello yes world"
var_dump(first3words("hello yes world.")); # => "hello yes world"
var_dump(first3words("hello yes")); # => "hello yes"
var_dump(first3words("hello")); # => "hello"
var_dump(first3words("a")); # => "a"
var_dump(first3words("")); # => ""
- 15,365
- 4
- 34
- 66
- 139,253
- 125
- 438
- 698
-
2Amazing this is fastest way so far for word limiting, this performs slighty better than explode, great job, well done. – VeeeneX Jul 01 '15 at 04:58
-
2Just a side note: If theres line breaks inside your string, this function will truncade every 20 words for every sentence (assuming you have a line break after every sentence). – Apr 10 '19 at 00:21
-
To match across lines ```((\w+[\W|\s]*){'.($limit-1).'}\w+|\W|\s)(?:(.*|\s))``` will need trim after for the trailing line breaks – Richard Muvirimi Nov 01 '21 at 12:25
To Nearest Space
Truncates to nearest preceding space of target character. Demo
$strThe string to be truncated$charsThe amount of characters to be stripped, can be overridden by$to_space$to_spacebooleanfor whether or not to truncate from space near$charslimit
Function
function truncateString($str, $chars, $to_space, $replacement="...") {
if($chars > strlen($str)) return $str;
$str = substr($str, 0, $chars);
$space_pos = strrpos($str, " ");
if($to_space && $space_pos >= 0)
$str = substr($str, 0, strrpos($str, " "));
return($str . $replacement);
}
Sample
<?php
$str = "this is a string that is just some text for you to test with";
print(truncateString($str, 20, false) . "\n");
print(truncateString($str, 22, false) . "\n");
print(truncateString($str, 24, true) . "\n");
print(truncateString($str, 26, true, " :)") . "\n");
print(truncateString($str, 28, true, "--") . "\n");
?>
Output
this is a string tha...
this is a string that ...
this is a string that...
this is a string that is :)
this is a string that is--
- 30,630
- 38
- 174
- 276
use explode() .
Example from the docs.
// Example 1
$pizza = "piece1 piece2 piece3 piece4 piece5 piece6";
$pieces = explode(" ", $pizza);
echo $pieces[0]; // piece1
echo $pieces[1]; // piece2
note that explode has a limit function. So you could do something like
$message = implode(" ", explode(" ", $long_message, 20));
- 26,673
- 7
- 73
- 94
-
1+1 WOW, I've been using explode since ever and I've never noticed the $limit argument before. – Alix Axel Aug 13 '09 at 09:19
-
1Explode's limit function does not act as suggested in this context. See http://www.php.net/manual/en/function.explode.php Example #2, positive limit. – Aaron Jul 06 '10 at 19:48
-
3@Tegeril is correct. Though this would fix it: `$words = implode(" ", array_slice( explode(" ", $t), 0, $count) );` – Dominik Feb 01 '14 at 00:02
-
1@Dominik, You nailed it. This worked immediately, its simple, very understandable and efficient. Thanks to you and to Tegeril for the first part. – Samuel Ramzan Apr 03 '19 at 19:01
Simple and fully equiped truncate() method:
function truncate($string, $width, $etc = ' ..')
{
$wrapped = explode('$trun$', wordwrap($string, $width, '$trun$', false), 2);
return $wrapped[0] . (isset($wrapped[1]) ? $etc : '');
}
- 71
- 1
- 1
-
This is what I use.. was going to add something like this as an answer so upvoting you instead ;-) – Eaten by a Grue Feb 01 '16 at 21:38
Try regex.
You need something that would match 20 words (or 20 word boundaries).
So (my regex is terrible so correct me if this isn't accurate):
/(\w+\b){20}/
And here are some examples of regex in php.
- 68,254
- 33
- 142
- 199
Its not my own creation, its a modification of previous posts. credits goes to karim79.
function limit_text($text, $limit) {
$strings = $text;
if (strlen($text) > $limit) {
$words = str_word_count($text, 2);
$pos = array_keys($words);
if(sizeof($pos) >$limit)
{
$text = substr($text, 0, $pos[$limit]) . '...';
}
return $text;
}
return $text;
}
With triple dots:
function limitWords($text, $limit) {
$word_arr = explode(" ", $text);
if (count($word_arr) > $limit) {
$words = implode(" ", array_slice($word_arr , 0, $limit) ) . ' ...';
return $words;
}
return $text;
}
- 878
- 1
- 7
- 13
If you code on Laravel just use Illuminate\Support\Str
here is example
Str::words($category->publication->title, env('WORDS_COUNT_HOME'), '...')
Hope this was helpful.
- 704
- 1
- 6
- 14
Split the string (into an array) by <space>, and then take the first 20 elements of that array.
- 15,790
- 19
- 74
- 133
-
-
won't work if there are punctuations but with no space after them, such as "hello,world". – nonopolarity Jun 08 '09 at 14:58
-
2@Jian Lin That's a problem with the user entering poor data, not the script. – ceejayoz Jun 08 '09 at 14:59
-
1
-
-
-
-
-
A common problem when creating dynamic web pages (where content is sourced from a database, content management system or external source such as an RSS feed) is that the input text can be too long and cause the page layout to 'break'.
One solution is to truncate the text so that it fits on the page. This sounds simple, but often the results aren't as expected due to words and sentences being cut off at inappropriate points.
- 333,516
- 69
- 632
- 626
This worked me for UNICODE (UTF8) sentences too:
function myUTF8truncate($string, $width){
if (mb_str_word_count($string) > $width) {
$string= preg_replace('/((\w+\W*|| [\p{L}]+\W*){'.($width-1).'}(\w+))(.*)/', '${1}', $string);
}
return $string;
}
- 49,021
- 18
- 212
- 206
Try below code,
$text = implode(' ', array_slice(explode(' ', $text), 0, 32))
echo $text;
- 5,547
- 2
- 40
- 52
- 21
- 3
based on 動靜能量's answer:
function truncate_words($string,$words=20) {
return preg_replace('/((\w+\W*){'.($words-1).'}(\w+))(.*)/', '${1}', $string);
}
or
function truncate_words_with_ellipsis($string,$words=20,$ellipsis=' ...') {
$new = preg_replace('/((\w+\W*){'.($words-1).'}(\w+))(.*)/', '${1}', $string);
if($new != $string){
return $new.$ellipsis;
}else{
return $string;
}
}
- 50,380
- 51
- 156
- 196
Something like this could probably do the trick:
<?php
$words = implode(' ', array_slice(split($input, ' ', 21), 0, 20));
- 22,961
- 20
- 67
- 89
Another solution :)
$aContent = explode(' ', $cContent);
$cContent = '';
$nCount = count($aContent);
for($nI = 0; ($nI < 20 && $nI < $nCount); $nI++) {
$cContent .= $aContent[$nI] . ' ';
}
trim($cContent, ' ');
echo '<p>' . $cContent . '</p>';
- 105
- 1
- 4
To limit words, am using the following little code :
$string = "hello world ! I love chocolate.";
$explode = array_slice(explode(' ', $string), 0, 4);
$implode = implode(" ",$explode);
echo $implode;
$implot will give : hello world ! I
- 21
- 1
function getShortString($string,$wordCount,$etc = true)
{
$expString = explode(' ',$string);
$wordsInString = count($expString);
if($wordsInString >= $wordCount )
{
$shortText = '';
for($i=0; $i < $wordCount-1; $i++)
{
$shortText .= $expString[$i].' ';
}
return $etc ? $shortText.='...' : $shortText;
}
else return $string;
}
- 129
- 1
- 11
Here is what I have implemented.
function summaryMode($text, $limit, $link) {
if (str_word_count($text, 0) > $limit) {
$numwords = str_word_count($text, 2);
$pos = array_keys($numwords);
$text = substr($text, 0, $pos[$limit]).'... <a href="'.$link.'">Read More</a>';
}
return $text;
}
As you can see it is based off karim79's answer, all that needed changing was that the if statement also needed to check against words not characters.
I also added a link to main function for convenience. So far it hsa worked flawlessly. Thanks to the original solution provider.
- 745
- 3
- 15
- 29
Here's one I use:
$truncate = function( $str, $length ) {
if( strlen( $str ) > $length && false !== strpos( $str, ' ' ) ) {
$str = preg_split( '/ [^ ]*$/', substr( $str, 0, $length ));
return htmlspecialchars($str[0]) . '…';
} else {
return htmlspecialchars($str);
}
};
return $truncate( $myStr, 50 );
- 2,238
- 2
- 22
- 26
Lets assume we have the string variables $string, $start, and $limit we can borrow 3 or 4 functions from PHP to achieve this. They are:
- script_tags() PHP function to remove the unnecessary HTML and PHP tags (if there are any). This wont be necessary, if there are no HTML or PHP tags.
- explode() to split the $string into an array
- array_splice() to specify the number of words and where it'll start from. It'll be controlled by vallues assigned to our $start and $limit variables.
and finally, implode() to join the array elements into your truncated string..
function truncateString($string, $start, $limit){ $stripped_string =strip_tags($string); // if there are HTML or PHP tags $string_array =explode(' ',$stripped_string); $truncated_array = array_splice($string_array,$start,$limit); $truncated_string=implode(' ',$truncated_array); return $truncated_string; }
It's that simple..
I hope this was helpful.
- 581
- 5
- 9
-
What does this add that the literally dozens of answers this question already has doesn't? – GordonM Jun 20 '18 at 14:02
function limitText($string,$limit){
if(strlen($string) > $limit){
$string = substr($string, 0,$limit) . "...";
}
return $string;
}
this will return 20 words. I hope it will help
- 1
- 1
- 3
- 5
I made my function:
function summery($text, $limit) {
$words=preg_split('/\s+/', $text);
$count=count(preg_split('/\s+/', $text));
if ($count > $limit) {
$text=NULL;
for($i=0;$i<$limit;$i++)
$text.=$words[$i].' ';
$text.='...';
}
return $text;
}
- 384
- 4
- 10
$text='some text';
$len=strlen($text);
$limit=500;
// char
if($len>$limit){
$text=substr($text,0,$limit);
$words=explode(" ", $text);
$wcount=count($words);
$ll=strlen($words[$wcount]);
$text=substr($text,0,($limit-$ll+1)).'...';
}
-
Welcome to Stack Overflow! Please don't answer just with source code. Try to provide a nice description about how your solution works. See: [stackoverflow.com/help/how-to-answer](https://stackoverflow.com/help/how-to-answer). Thanks! – Matt Ke Mar 05 '19 at 22:21
function wordLimit($str, $limit) {
$arr = explode(' ', $str);
if(count($arr) <= $limit){
return $str;
}
$result = '';
for($i = 0; $i < $limit; $i++){
$result .= $arr[$i].' ';
}
return trim($result);
}
echo wordLimit('Hello Word', 1); // Hello
echo wordLimit('Hello Word', 2); // Hello Word
echo wordLimit('Hello Word', 3); // Hello Word
echo wordLimit('Hello Word', 0); // ''
- 19
- 1
- 4
Truncate the text surrounding a specific set of keywords.
The goal is to be able to convert this:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna liqua. Ut enim ad minim veniam.
Into this:
...consectetur adipisicing elit, sed do eiusmod tempor...
Which is a very common situation when displaying search results, excerpts, etc.
I've posted a solution to that specific casuistic in this thread, hoping that it would be helpful for people landing here, too.
- 7,548
- 1
- 26
- 20
- 420
- 2
- 6
-
This is not useful because it doesn't recognize words, just string/character length. – mickmackusa Nov 09 '17 at 22:52
function limit_word($start,$limit,$text){
$limit=$limit-1;
$stripped_string =strip_tags($text);
$string_array =explode(' ',$stripped_string);
if(count($string_array)>$limit){
$truncated_array = array_splice($string_array,$start,$limit);
$text=implode(' ',$truncated_array).'...';
return($text);
}
else{return($text);}
}
-
12 answers in two days with only a code sample in a old post. you definitely should read this : https://stackoverflow.com/help/how-to-answer. – Frankich Mar 07 '19 at 14:39
-
Can you explain that further? Why do you need all that code, and what **exactly** does it do? – Nico Haase Mar 07 '19 at 14:50