$string = "the man has a large wingspan";
$words = array("man","span");
foreach ($words as $word){
/*** quote the text for rejex ***/
$word = preg_quote($word);
/*** highlight the words ***/
if( !preg_match( '/<(.*)>/', preg_match("/($word)/i",$string) ) ) {
$string = preg_replace("/($word)/i", '<span class="highlight">\\1</span>', $string);
}
}
I’m having some issues trying to highlight some search results.
I am highlighting the words that a user searches. The code iterates through each word in the array and then redefines the string to include a span with a class attribute added to it. The problem is whenever a partial match is made on a subsequent iteration there is a chance that that match is inbetween the html tags.
For example with the above code
Input: the man has a large wingspan
Output:
the <<span class="highlight">span</span> class="highlight">man</<span class="highlight">span</span>> has a large wingspan
Desired Output
the <span class="highlight">man has a large wing<span class="highlight">span</span>
You don’t need regex for this. I’d suggest to use [fphp]strtr[/fphp] instead.
$string = "the man has a large wingspan";
$words = array("man","span");
$trans=array();
foreach($words as $word) {
$tr[$word]='<span class="highlight">'.$word.'</span>';
}
$string=strtr($string, $trans);
The good news is that strtr(); searches for partial words so that if the word is “Hippo” it will highlight “Hip” if the search string is “hip”
Unfortunately I have the same problem as before. It replaces the “span” that is present in the html tag instead of just the span present in the word “wingspan”
I attached the file below so that you can see for yourself what the output is.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<style type="text/css">
.highlight{
font-weight: bold;
color:red;
}
</style>
</head>
<body>
<?php
//*** First Test Checks if it replaces span in html tags
echo highlight('the man has a <span class="highlight">large</span> wingspan', "man span HA");
echo "<br /><br /><br /> 2:";
//***Second checks to see if the removal of span from wingspan makes it work
echo highlight('the man has a large wing', "man span HA");
?>
</body>
</html>
<?php
function highlight($string, $search){
/*** Split search string into arrays of words***/
$words = explode(" ", $search);
$trans=array();
/*** Go through all the words ***/
foreach ($words as $word){
/*** quote the text for rejex ***/
// $word = preg_quote($word);
/*** highlight the words ***/
$trans[$word]='<span class="highlight">'.$word.'</span>';
$string=strtr($string, $trans);
// if( !preg_match( '/<(.*)>/', preg_match("/($word)/i",$string) ) ) {
// if( !preg_match( '/<span\\b[^>]*>(.*?)($word)(.*?)<\\/span>/', $string) ){
// if( (!preg_match( '/<(.*?)\\b(.*?)($word)(.*?)<\\/(.*?)>/', $string))){
// echo "here";
// $string = preg_replace("/($word)/i", '<span //class="highlight">\\1</span>', $string);
// }
}
/*** Return String ***/
return $string;
}
?>
Output 1:
the <<span class=“highlight”>spanspan> class=“highlight”><span class=“highlight”>manspan>span class=“highlight”>spanspan>> has a <<span class=“highlight”>spanspan> class=“highlight”>largespan class=“highlight”>spanspan>> wing<span class=“highlight”>spanspan>
Taking HTML into account is extremely complicated and basically means you’d have to write a full blown HTML parser in order to it.
This would a take a few hours, if not days.
Well, I don’t really understand how it works, mainly because I am just staring at it with a blank face but change a few lines here to split the needle into separate search terms and by golly it’s perfect. Thanks, this is exactly what I wanted.