Page 1 of 3
Chopping text question
Posted: Mon Apr 02, 2007 3:04 pm
by Sinemacula
In an earlier thread –
viewtopic.php?t=25351 – I found this:
feyd wrote:Code: Select all
<?php
$text = 'Jack went to the store to get himself a large bottle of whiskey';
preg_match('#^\s*(.{26,}?)\s+.*$#', $text, $match);
var_export($match);
?>
outputs
Code: Select all
array (
0 => 'Jack went to the store to get himself a large bottle of whiskey',
1 => 'Jack went to the store to get',
)
Which
almost does exactly what I want...
My problem is that I've set the length to 15, but some of my text items are less than 15 characters long, so they're getting cut off completely.
e.g.
Code: Select all
<?php
$text = 'Personality & Personal Growth'
preg_match('#^\s*(.{15,}?)\s+.*$#s', $book, $match);
var_export($match);
outputs
Code: Select all
array (0 => 'Personality & Personal Growth',
1 => 'Personality & Personal',)
but
Code: Select all
<?php
$text = 'Testing'
preg_match('#^\s*(.{15,}?)\s+.*$#s', $book, $match);
var_export($match);
outputs
What do I need to change so that when $text is less than the set value in the preg_match statment, the whole $text will be returned?
Thanks,
Scott
Posted: Mon Apr 02, 2007 3:19 pm
by Oren
Please tell us exactly what you want to do, since I've got the feeling that this code is not what you real want.
I think what you really need is
substr().
Posted: Mon Apr 02, 2007 3:28 pm
by Sinemacula
I want to have the results from a mysql query displayed such that they will be truncated at 15 characters AND such that if truncation would happen in the middle of a word, it will go to the next space before cutting it off.
So,
- if $text is less than 15 characters, the whole of $text is displayed
- if $text is more than 15 characters, it will be truncated at the 15th character
- BUT, if the 15th character of $text is in the middle of a word, it will go to the next space
Posted: Mon Apr 02, 2007 3:42 pm
by Oren
I don't know, but MySQL might have a built-in function which does exactly this thing for you - if such a function exists, it will most likely be faster than doing it on the PHP side.
Posted: Mon Apr 02, 2007 3:53 pm
by Sinemacula
Well, I
think I need to do it with php because it's only the display of the results that I want shortened in one part of a page.
The full code I'm using is:
Code: Select all
$book=$myrow3['title'];
preg_match('#^\s*(.{15,}?)\s+.*$#s', $book, $match);
echo "<li><a href=\"http://astore.amazon.com/itp-ma4cs-20/detail/".$myrow3['isbn']."\" target=\"iframe\" title=\"".$book."\">".$match[1]."...</a></li>";
So, in this case, it's $book that I want to display only 15 characters of in one place, but I want the whole thing displaying in another place... so I still need to have the whole value of $book available. What I've got there works fine, except for when $book is less than 15 characters long - in which case it displays nothing for $match[1].

Posted: Mon Apr 02, 2007 3:59 pm
by Oren
You said you need the "whole thing" in another page - which means a new query anyway, so my argument still holds

Posted: Mon Apr 02, 2007 4:15 pm
by Sinemacula
Actually, I need the "whole thing" in another "place"

-- same page, same statement even (notice $book and $match[1]), so only one query (in this particular case, since it's creating a url link, I want the shortened version to display, but the full version as the link title).
Posted: Mon Apr 02, 2007 6:19 pm
by onion2k
Code: Select all
SELECT title,
SUBSTR(title,1,LOCATE(' ',title,15)) as trimmed_title
FROM `my_table` WHERE 1
Posted: Mon Apr 02, 2007 6:55 pm
by RobertGonzalez
The manual is a wonderful place to learn PHP.
Posted: Mon Apr 02, 2007 9:29 pm
by feyd
The code requires a passed string to be 15 characters or more before it will find anything.
It was meant to be used in conjunction with
strlen().
Posted: Mon Apr 02, 2007 11:41 pm
by Sinemacula
I tried some of the functions examples in the php manual pages, but they wouldn't work because I'm using it in a recursive section, and I kept getting an error message that I could not "redeclare" the function.
However, I found that adding a strlen() statement did what I need, so I've got:
Code: Select all
$book=$myrow3['title'];
$limit='18';
if(strlen($book) > $limit)
{
preg_match('#^\s*(.{12,}?)\s+.*$#s', $book, $match);
$trimmed_book = $match[1]."...";
} else {
$trimmed_book = $book;
}
which appears to be working fine for what I need.
Thanks,
Scott
Posted: Tue Apr 03, 2007 12:28 am
by Sinemacula
Shortly after posting that I'd found a working solution, I had a hunch to try something else... I think this solution is better and solves the actual problem I was having, rather than being a "workaround" that might not work for all scenarios.
Here's what I'm now using, successfully:
Code: Select all
$book=$myrow3['title'];
preg_match('#^\s*(.{11,}?)\s+.*$#s', $book, $match);
if(strlen($match[1]) > '0')
{
$trimmed_book = $match[1]."...";
} else {
$trimmed_book = $book;
}
Posted: Tue Apr 03, 2007 12:46 am
by Kieran Huggins
why not just
wordwrap() the text then take the first line... seems much cleaner, and faster to me!
Posted: Tue Apr 03, 2007 10:21 am
by RobertGonzalez
This is really not that hard. In fact, I got this from the manual page that I had linked to in my last post, a few comments down...
Code: Select all
<?php
function truncate_long_string($string, $max_length) {
if (strlen($string) > $max_length) {
$string = substr($string, 0, $max_length);
if (($pos = strrpos($string, ' ')) === false) {
return substr($string, 0, $max_length) . ' ...';
}
return substr($string, 0, $pos) . ' ...';
} else {
return $string;
}
}
$test_string = 'If only there were a function that would cut strings down but not cut words in the process.';
/**
* Outputs: If only there ...
*/
echo truncate_long_string($test_string, 15) . '<br />';
/**
* Outputs: If only there were a ...
*/
echo truncate_long_string($test_string, 25) . '<br />';
/**
* Outputs: If only there were a function that ...
*/
echo truncate_long_string($test_string, 40) . '<br />';
/**
* Outputs: If only there were a function that would cut strings ...
*/
echo truncate_long_string($test_string, 55) . '<br />';
/**
* Outputs: If only there were a function that would cut strings down but not cut words in the process.
*/
echo truncate_long_string($test_string, 150) . '<br />';
?>
Posted: Tue Apr 03, 2007 2:49 pm
by Sinemacula
Everah wrote:This is really not that hard. In fact, I got this from the manual page that I had linked to in my last post, a few comments down...
Unfortunately, the code you posted, just like the other functions I tried from the manual page you referenced, does not work for my situation... using that code, I get the following error:
Code: Select all
Fatal error: Cannot redeclare truncate_long_string() (previously declared in...
I don't know enough to know if there's a way around that, or a "fix" for such functions such that they can deal with the recursive nature of what I'm doing, but the preg_match code followed by the strlen code as I posted above is working fine.
Now, if I could just figure out the right way to do my mysql query as a JOIN rather than three separate queries (
viewtopic.php?p=370960 ), I'd be set!
