Reputation: 139872
For example, it just returns the snippet around which the searching keyword exists.
And part of the text is replaced by "...".
Is it possible to achieve that goal with PHP and MySQL?
Upvotes: 6
Views: 6071
Reputation: 9
this is my modified function
function excerpt_2($text, $query, $limit_chars_between, $results_divider, $b_highlight_class)
{
if ((trim($text) === '') || (trim($query) === '')) {
return false;
}
$text = "\n" . chop(trim($text)) . "\n"; // IMPORTANT START/END with "\n" - for search first/last entries
//words
$words = join('|', explode(' ', preg_quote(trim($query))));
//lookahead/behind assertions ensures cut between words
$s_preg_charset = '\s\x00-/:-@\[-`{-~'; //character set for start/end of words
preg_match_all('#(?<=[' . $s_preg_charset . ']).{0,' . $limit_chars_between . '}((' . $words . ').{0,' . $limit_chars_between . '})+(?=[' . $s_preg_charset . '])#ius', $text, $matches, PREG_OFFSET_CAPTURE);
$result = $is_text_truncated = false;
$first_founded_pos = $last_founded_pos = -1;
$a_results = array();
if (count($matches[0]) > 0) {
foreach ($matches[0] as $a_line) {
if ($first_founded_pos < 0) {
$first_founded_pos = $a_line[1];
}
$a_results[] = chop(trim($a_line[0])); //htmlspecialchars($a_line[0], 0, 'UTF-8');
}
if (count($a_results)) {
$result = join(' ' . $results_divider . ' ', $a_results);
if (($first_founded_pos > $limit_chars_between)) {
$result = $results_divider . '' . $result;
}
$last_el_matches = end($matches);
$last_founded_pos = $last_el_matches[0][1];
if (($last_founded_pos + $limit_chars_between) < mb_strlen($text, 'UTF-8')) {
$result .= $results_divider;
}
$is_text_truncated = true;
$result = preg_replace('#' . $words . '#iu', '<b class="' . $b_highlight_class . '">$0</b>', $result);
}
}
return array(
'text' => $result,
'is_text_truncated' => $is_text_truncated,
);
}
Upvotes: 0
Reputation: 2485
$snippet = "//mysql query";
function trimmer($updates,$wrds){
if(strlen($updates)<=$wrds){
return $updates;
}else{
$marker = strrpos(substr($updates,0,$wrds),' ');
$string = substr(substr($updates,0,$wrds),0,$marker)."...";return $string;
}
echo trimmer($snippet,200); //You can send the snippet string to this function it searches for the last space if string length is greater than 200 and adds "..." to it
This is probably what you want (EDIT):
$string1="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.";
function trimmer($updates,$wrds,$pos){
if(strlen($updates)<=$wrds) {
return $updates;
} else {
$marker = strrpos(substr($updates,$pos,$wrds),' ');
$string = substr(substr($updates,$pos,$wrds),0,$marker)."...";
return $string;
}
}
$pos = strpos($string1, "dummy");
echo trimmer($string1,100,$pos);
Upvotes: 0
Reputation: 654
My solution for multiple multiple keywords and multiple occurences (also works for accents case insensitive):
function excerpt($text, $query)
{
//words
$words = join('|', explode(' ', preg_quote($query)));
//lookahead/behind assertions ensures cut between words
$s = '\s\x00-/:-@\[-`{-~'; //character set for start/end of words
preg_match_all('#(?<=['.$s.']).{1,30}(('.$words.').{1,30})+(?=['.$s.'])#uis', $text, $matches, PREG_SET_ORDER);
//delimiter between occurences
$results = array();
foreach($matches as $line) {
$results[] = htmlspecialchars($line[0], 0, 'UTF-8');
}
$result = join(' <b>(...)</b> ', $results);
//highlight
$result = preg_replace('#'.$words.'#iu', "<span class=\"highlight\">\$0</span>", $result);
return $result;
}
This is example result for query = "švihov prohlídkám"
Upvotes: 6
Reputation: 95900
Modified deceze's function slightly to allow multiple phrases. e.g. your phrase can be "testa testb" and if it does not find testa, then it will go to testb.
function excerpt($text, $phrase, $radius = 100, $ending = "...") {
$phraseLen = strlen($phrase);
if ($radius < $phraseLen) {
$radius = $phraseLen;
}
$phrases = explode (' ',$phrase);
foreach ($phrases as $phrase) {
$pos = strpos(strtolower($text), strtolower($phrase));
if ($pos > -1) break;
}
$startPos = 0;
if ($pos > $radius) {
$startPos = $pos - $radius;
}
$textLen = strlen($text);
$endPos = $pos + $phraseLen + $radius;
if ($endPos >= $textLen) {
$endPos = $textLen;
}
$excerpt = substr($text, $startPos, $endPos - $startPos);
if ($startPos != 0) {
$excerpt = substr_replace($excerpt, $ending, 0, $phraseLen);
}
if ($endPos != $textLen) {
$excerpt = substr_replace($excerpt, $ending, -$phraseLen);
}
return $excerpt;
}
Highlight function
function highlight($c,$q){
$q=explode(' ',str_replace(array('','\\','+','*','?','[','^',']','$','(',')','{','}','=','!','<','>','|',':','#','-','_'),'',$q));
for($i=0;$i<sizeOf($q);$i++)
$c=preg_replace("/($q[$i])(?![^<]*>)/i","<span class=\"highlight\">\${1}</span>",$c);
return $c;}
Upvotes: 9
Reputation: 522125
function excerpt($text, $phrase, $radius = 100, $ending = "...") {
$phraseLen = strlen($phrase);
if ($radius < $phraseLen) {
$radius = $phraseLen;
}
$pos = strpos(strtolower($text), strtolower($phrase));
$startPos = 0;
if ($pos > $radius) {
$startPos = $pos - $radius;
}
$textLen = strlen($text);
$endPos = $pos + $phraseLen + $radius;
if ($endPos >= $textLen) {
$endPos = $textLen;
}
$excerpt = substr($text, $startPos, $endPos - $startPos);
if ($startPos != 0) {
$excerpt = substr_replace($excerpt, $ending, 0, $phraseLen);
}
if ($endPos != $textLen) {
$excerpt = substr_replace($excerpt, $ending, -$phraseLen);
}
return $excerpt;
}
Shamelessly stolen from the Cake TextHelper.
Upvotes: 4