Highlight multiple keywords advanced - php

I tried most of solution answered here but all of them have same problem which is my question here.
I use this function for highligh search results:
function highlightWords($searchtext, $searchstrings){
$searchstrings = preg_replace('/\s+/', ' ', trim($searchstrings));
$words = explode(' ', $searchstrings);
$highlighted = array();
foreach ( $words as $word ){
$highlighted[] = "<font color='#00f'><b>".$word."</b></font>";
}
return str_replace($words, $highlighted, $searchtext);
}
Problem occurs when i search text with 2 or more strings separated with spaces and any of them have any of HTML code from my highlighted array.
For example, searchtext="I have max system performance" AND searchstrings="max f"
In first iteration foreach will replace every max with <font color='#00f'><b>max</b></font>
In second iteration it will replace every f with <font color='#00f'><b>f</b></font>
Second iteration will also replace html tags inserted in first replacement!
So it will replace f in string <font color='#00f'> also?
Any suggestion?
Thanks
Miodrag

<?php
$searchtext = "I have max system performance";
$searchstrings = "max f";
$searchstrings = preg_replace('/\s+/', ' ', trim($searchstrings));
$words = explode(' ', $searchstrings);
$highlighted = array();
foreach ( $words as $word ){
$highlighted[] = "<font color='#00f'><b>".$word."</b></font>";
}
echo strtr($searchtext, array_combine($words, $highlighted));
?>

Maybe this is good Solution for you?
function highlightWords($searchtext, $searchstrings){
$searchstrings = preg_replace('/\s+/', ' ', trim($searchstrings));
$words = explode(' ', $searchstrings);
$highlighted = array();
foreach ( $words as $word ){
$highlighted[] = '<span class="highlighted-word">'.$word.'</span>';
}
return str_replace($words, $highlighted, $searchtext);
}
echo highlightWords('I have max system performance', 'max f');
?>
You need to add a little bit CSS on your Page:
<style>
.highlighted-word {
font-weight: bold;
}
</style>
Outputs:
I have max system performance
---
UPDATE:
If you like to hightlight the complete word, look at this:
function highlightCompleteWords($searchtext, $searchstrings){
$searchstrings = preg_replace('/\s+/', ' ', trim($searchstrings));
$words = explode(' ', $searchstrings);
$highlighted = array();
foreach ( $words as $word ){
$searchtext = preg_replace("/\w*?".preg_quote($word)."\w*/i", "<span class='highlighted-word'>$0</span>", $searchtext);
}
return $searchtext;
}
echo highlightCompleteWords('I have max system performance', 'max f');
Outputs: I have max system performance

I might not fully understand your question, but I guess you want to highlight every matched word in the search string.
You could probably just do something like:
$returnString = $searchtext;
foreach ( $words as $word ){
$returnString = preg_replace('/\b'.$word.'\b/i', "<font color='#00f'><b>$0</b></font>", $returnString);
}
return $returnString;
This would output: "I have max system performance"
Since the "f" wouldn't get matched
EDIT - This is if you wanna match part of a word as well.
Kind of ugly but I believe this will fork for you
$returnString = $searchtext;
foreach ( $words as $word ){
if(strlen($word)>2){
$returnString = preg_replace('/'.$word.'/i', "§§§$0###", $returnString);
}
}
$returnString = preg_replace("/\§§§/","<font color='#00f'><b>", $returnString);
$returnString = preg_replace("/\###/","</b></font>", $returnString);
return $returnString;

Try the following
foreach ( $words as $word ){
if(strlen ($word)>2)
{
$highlighted[] = "<font color='#00f'><b>".$word."</b></font>";
}
}

Related

Delete words that match the pattern on the string

I have to filter a string according to words similar to the pattern.
I need to delete words that match the formula:
<?php
$string = 'armin van burren yummy';
$pattern = 'a%n v%n b%n';
//result: Yummy
$string = 'Beyonce - love on top';
$pattern = 'b%e';
//result: Love on top
$string = 'Ed Sheeran - Shape of You';
$pattern = 'e_ s_____n';
//result: Shape of You
?>
Do you have any idea how to get this result, maybe there is some function in php. I tried to search, unfortunately I didn't find any information. Thank you for all the help and examples
This code works for me, is it possible to limit the amount of foreach for this code (performance is concerned)?
function filterlike($arr, $like){
if ($arr && $like){
$like = preg_replace('/_{1,}/','.*', $like);
$like = preg_replace('/%/','.*', $like);
$like = explode(' ', $like);
$filter = array();
foreach ($arr as $a){
foreach ($like as $l){
$a = preg_replace('/'.$l.'/', '', $a);
}
$filter[] = $a;
}
return $filter;
}
}
print_r(filterlike(array('armin', 'van', 'burren', 'jummy'), 'a%n v%n b%n'));
print_r(filterlike(array('armin', 'van', 'burren', 'jummy'), 'a___n v_n b____n'));

PHP find tags in content text and wrap in <a> tags and set limit the number of links

Im finding keywords "denounce,and,demoralized" in a string, and wrapping it in "html a" tags to change it to link with following function...
function link2tags($text, $tags){
$tags = preg_replace('/\s+/', ' ', trim($tags));
$words = explode(',', $tags);
$linked = array();
foreach ( $words as $word ){
$linked[] = ''.$word.'';
}
return str_replace($words, $linked, $text);
}
echo link2tags('we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment', 'denounce,and,demoralized');
The output of the above function is as follows...
Output:
we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment
Here, the word "and" is linked 2 times I want to limit the number of links to a word
Repeat words are only linked once
You need to get only first occurrence of words and then need to replace those. Check below code:
function link2tags($text, $tags){
$tags = preg_replace('/\s+/', ' ', trim($tags));
$words = explode(',', $tags);
$linked = array();
$existingLinks = array();
foreach ( $words as $word ){
if (!in_array($word, $existingLinks)) {
$existingLinks[] = $word;
$linked[] = ''.$word.'';
}
}
foreach ($existingLinks as $key => $value) {
$text = preg_replace("/".$value."/", $linked[$key], $text, 1);
}
return $text;
}
Hope it helps you.
Here you can check existing word as below:
if(!in_array($word,$alreadyusedword)) {
$linked[] = ''.$word.'';
$alreadyusedword[] = $word;
}

Split string with read more by word count

I need a split string with 2 divs, by the first div with 20 words and last div with rest of words to make read more link with javascript.
At the moment I have only character count limit.
How can I do word splitting?
if ( $term && ! empty( $term->description ) ) {
$first = substr($term->description, 0, 400);
$rest = substr($term->description, 400);
echo '<div class="term-description"><div class="first-letter">'.$first.'</div><div class="last-letter">'.$rest.'</div></div>';
}
This code does the trick:
<?php
function SplitStringToParts($sourceInput, &$first, &$rest, $countWordsInFirst = 20)
{
$arr_exploded = explode(" ", $sourceInput);
$arr_part1 = array_slice($arr_exploded, 0, $countWordsInFirst);
$arr_part2 = array_slice($arr_exploded, $countWordsInFirst);
$first = implode(" ",$arr_part1);
$rest = implode(" ",$arr_part2);
}
$str = "str1 str2 str3 str4 str5 str6 str7 str8 str9 str10 str11 str12 str13 str14 str15 str16 str17 str18 str19 str20 str21 str22 str23 str24";
SplitStringToParts($str,$first,$rest,20);
echo $first."<br>";
echo $rest."<br>";
Output is:
str1 str2 str3 str4 str5 str6 str7 str8 str9 str10 str11 str12 str13 str14 str15 str16 str17 str18 str19 str20
str21 str22 str23 str24
Use SplitStringToParts function. In your case you should call it as:
SplitStringToParts($term->description, $first, $rest, 20);
After it $first, $rest will keep your result
Found solution:
<?php
// sentence teaser
// this function will cut the string by how many words you want
function word_teaser($string, $count){
$original_string = $string;
$words = explode(' ', $original_string);
if (count($words) > $count){
$words = array_slice($words, 0, $count);
$string = implode(' ', $words);
}
return $string;
}
// sentence reveal teaser
// this function will get the remaining words
function word_teaser_end($string, $count){
$words = explode(' ', $string);
$words = array_slice($words, $count);
$string = implode(' ', $words);
return $string;
}
?>
$string = "We are BrightCherry web design, and we're going to show you how to write a function to crop a string by a certain amount of words."
//this will echo the first 10 words of the string
echo word_teaser($string, 10);
$string = "We are BrightCherry web design, and we're going to show you how to write a function to crop a string by a certain amount of words."
//this will echo the words after the first 10 words
echo word_teaser_end($string, 10);

Converting string with html styling ags to title case

I'm using this function to convert text to title case:
function strtotitle($title) {
$smallwordsarray = array( 'of','a','the','and','an','or','nor','but','is','if','then','else','when', 'at','from','by','on','off','for','in','to','into','with','it', 'as' );
// Split the string into separate words
$words = explode(' ', $title);
foreach ($words as $key => $word) {
// If this word is the first, or it's not one of our small words, capitalise it
// with ucwords().
if ($key == 0 or !in_array($word, $smallwordsarray))
$words[$key] = ucwords($word);
}
// Join the words back into a string
$newtitle = implode(' ', $words);
return $newtitle;
}
The issue is that if text is bold, italic etc then the function does not work and will not title case the word.
For example: "This is a simple sentence" will be converted to "This is a Simple Sentence". But "This is a simple sentence" will be converted to "This is a simple Sentence".
Any help greatly appreciated.
If you are talking about HTML tags and you want to save it, you can use this implementation:
<?php
/* Your old string */
$string = "<b>asd</b>";
/* Remove html code */
$old = strip_tags($string);
/* Upper case the first letter */
$new = ucfirst($old);
/* Replace old word to new word in $string */
$real = str_replace($old,$new,$string);
/* Here the new string and the old string */
echo $real." ".$string;
?>
So the solution in your code looks like :
function strtotitle($title) {
$smallwordsarray = array( 'of','a','the','and','an','or','nor','but','is','if','then','else','when', 'at','from','by','on','off','for','in','to','into','with','it', 'as' );
// Split the string into separate words
$words = explode(' ', $title);
foreach ($words as $key => $word) {
// If this word is the first, or it's not one of our small words, capitalise it
// with ucwords().
if ($key == 0 or !in_array(strip_tags($word), $smallwordsarray)) {
$old = strip_tags($word);
$new = ucfirst($old);
$words[key] = str_replace($old,$new,$word);
}
}
// Join the words back into a string
$newtitle = implode(' ', $words);
return $newtitle;
}
<?php
function strtotitle($title) {
$smallwordsarray = array( 'of','a','the','and','an','or','nor','but','is','if','then','else','when', 'at','from','by','on','off','for','in','to','into','with','it', 'as' );
$words = $temp = explode(' ', strip_tags($title));
foreach ($temp as $key => $word) {
if ($key == 0 or !in_array($word, $smallwordsarray)) $temp[$key] = ucwords($word);
}
foreach($words as $index => $word) $title = str_replace($word, $temp[$index], $title);
return $title;
}
var_dump(strtotitle('This is a simple sentence'));
var_dump(strtotitle('This is a <b>simple</b> <i>sentence</i>'));
You could use strip_tags this way:
function strtotitle($title) {
$smallwordsarray = array( 'of','a','the','and','an','or','nor','but','is','if','then','else','when', 'at','from','by','on','off','for','in','to','into','with','it', 'as' );
// Remove HTML tags
$titleWithoutTags = strip_tags($title);
// Split the string into separate words
$words = explode(' ', $titleWithoutTags);
foreach ($words as $key => $word) {
// If this word is the first, or it's not one of our small words, capitalise it
// with ucwords().
if ($key == 0 or !in_array($word, $smallwordsarray))
$words[$key] = ucwords($word);
}
// Join the words back into a string
$newtitle = implode(' ', $words);
return $newtitle;
}

Highlighting keywords in PHP search script

I have a PHP search script that queries a MySQL database and then parses the results through HTML to allow CSS styling. I want the script to highlight all of the keywords in the results that the user has search for. How can I do this with PHP?
My PHP script is:
<?php
mysql_connect("localhost","username","password");
mysql_select_db("database");
if(!empty($_GET['q'])){
$query=mysql_real_escape_string(trim($_GET['q']));
$searchSQL="SELECT * FROM links WHERE `title` LIKE '%{$query}%' LIMIT 8";
$searchResult=mysql_query($searchSQL);
while ($row=mysql_fetch_assoc($searchResult)){
$results[]="<a href='{$row['url']}' class='webresult'><div class='title'>{$row['title']}</div><div class='desc'>{$row['description']}</div><div class='url'>{$row['url']}</div></a>";
}
if(empty($results)){
echo 'No results were found';
} else {
echo implode($results);
}
}
?>
Simplistically you could adapt the loop here:
$searchvar = trim($_GET['q']);
while ($row=mysql_fetch_assoc($searchResult)){
$description = str_replace($searchvar, '<span class="highlight">'.$searchvar."</span>", $row['description']);
$results .="<a href='{$row['url']}' class='webresult'>
<div class='title'>{$row['title']}</div>
<div class='desc'>{$description}</div>
<div class='url'>{$row['url']}</div></a>";
}
To make it a little better:
$searchvar = explode(" ", trim($_GET['q'])); //puts each space separated word into the array.
while ($row=mysql_fetch_assoc($searchResult)){
$description = $row['description'];
foreach($searchvar as $var) $description = str_replace($var, '<span class="highlight">'.$var."</span>", $description);
$description = str_replace($searchvar, '<span class="highlight">'.$searchvar."</span>", $row['description']);
$results .="<a href='{$row['url']}' class='webresult'>
<div class='title'>{$row['title']}</div>
<div class='desc'>{$description}</div>
<div class='url'>{$row['url']}</div></a>";
}
The benefit of the second one there is that if a user types in "ipod toudch yellow" you will be searching for "ipod", "toudch" and "yellow" which would negate the type and make the results more general.
You would need to exchange the single:
like '%query%'
with
foreach(explode(" ", trim($_GET['q']) as $searchvar) $where[] = "like '%$searchvar%'";
$wheresql = implode(" OR ", $where);
to get each search "word" to be looked for in the sql or you will have a limited search with a unrelated highlight.
i also found this solution to highlight each word of the results:
$text = $searchresults;
class highlight
{
public $output_text;
function __construct($text, $words)
{
$split_words = explode( " " , $words );
foreach ($split_words as $word)
{
$text = preg_replace("|($word)|Ui" , "<b>$1</b>" , $text );
}
$this->output_text = $text;
}
}
$highlight = new highlight($searchresults, $keywords);
echo $highlight;
In case that could help,
Regards,
Max
you can use regex or simply str replace to look for a particular string and add a span around it:
while ($row=mysql_fetch_assoc($searchResult)){
$str ="<a href='".$row['url']."' class='webresult'>";
$str .="<div class='title'>".$row['title']."</div>";
$str .="<div class='desc'>";
$str .= str_replace($query,"<span class='hightlighted'>".$query."</span>",$row['description']);
$str .="</div><div class='url'>".$row['url']."</div></a>";
$result[] = $str;
}
now the css:
span.highlighted {
background-color: yellow;
}
You can use str_replace. For each keyword the user uses, put it into the $search array, and also put it into a $replace array, but surround with with a classed span tag in the latter, which you can style with CSS later. For example:
$search = array('apple', 'orange');
$replace = array();
foreach ($search as $word)
{
$replace[] = "<span class='highlight'>$word</span>";
}
$string = str_replace($search, $replace, $string);
EDIT: assuming that $query just contains keywords delimited by a single whitespace, you could get the search array this way (with explode),
$search = explode(' ', $query);
Or, if you want to add more complex logic for processing the keywords out of the $query variable (like if you use query operators like +), you could use a for loop:
$queryTerms = explode(' ', $query);
$search = array();
foreach ($queryTerms as $term)
{
// do some processing of the $term (like delete "+"?)
// ...
$search[] = $processedTerm;
}

Categories