Here is an improved version of chud37.com's function. It now works with perfect matches, too - highlight('abc', 'abc') didn't work in the old version.
<?php
function highlight($haystack, $needle) {
if (strlen($haystack) < 1 || strlen($needle) < 1) {return $haystack;}
preg_match_all("/$needle+/i", $haystack, $match);
$exploded = preg_split("/$needle+/i",$haystack);
$replaced = "";
foreach($exploded as $e) {
foreach($match as $m)
if ($i < count($exploded)-1) {$replaced .= $e . "<font class=\"hl\">" . $m[0] . "</font>";} else {$replaced .= $e;}
$i++;
}
return $replaced;
}
?>
Description
str_ireplace() retourne une chaîne de caractères ou un tableau dont toutes les occurrences de search dans subject (en ignorant la casse), ont été remplacées par la valeur de replace. Si vous n'avez pas besoin de règles de recherche complexes, il est recommandé d'utiliser cette fonction à la place de preg_replace() avec l'option i.
Liste de paramètres
Si les paramètres search et replace sont des tableaux, alors la fonction str_ireplace() prendra une valeur de chaque tableau et les utilisera pour la recherche et le remplacement sur subject. Si le paramètre replace a moins de valeurs que le paramètre search, alors une chaîne de caractères vide sera utilisée comme valeur pour le reste des valeurs de remplacement. Si le paramètre search est un tableau et que le paramètre replace est une chaîne de caractères, alors cette chaîne de caractères de remplacement sera utililsée pour chaque valeur de search. L'inverse n'a pas de sens.
Si le paramètre search ou le paramètre replace sont des tableaux, leurs éléments sont traités du premier au dernier.
- search
-
La valeur à chercher, connue aussi sous le nom de needle. Un tableau peut être utilisé pour désigner plusieurs needles.
- replace
-
La valeur de remplacement utilisée pour chaque valeur trouvée dans search. Un tableau peut être utilisé pour désigner plusieurs remplacements.
- subject
-
Une chaîne de caractères ou un tableau dans lequel la recherche s'effectue, aussi connu sous le nom de haystack.
Si subject est un tableau, le remplacement est effectué sur chacun des éléments du sujet subject, et la valeur retournée est aussi un tableau.
- count
-
Si fournie, cette variable contiendra le nombre de remplacements effectués.
Valeurs de retour
Retourne une chaîne ou un tableau de remplacement.
Historique
| Version | Description |
|---|---|
| 5.0.0 | Ajout du paramètre count. |
Exemples
Exemple #1 Exemple avec str_ireplace()
<?php
$bodytag = str_ireplace("%body%", "black", "<body text=%BODY%>");
?>
Notes
Note: Cette fonction gère les chaînes binaires.
Ordre de remplacement
Vu le fait que la fonction str_ireplace() effectue les remplacements de la gauche vers la droite, elle peut remplacer une valeur précédemment insérée lors de remplacement multpiple. L'exemple #2 de la documentation de la fonction str_replace() sur la façon de traiter cette problématique.
Voir aussi
- str_replace() - Remplace toutes les occurrences dans une chaîne
- preg_replace() - Rechercher et remplacer par expression rationnelle standard
- strtr() - Remplace des caractères dans une chaîne
After searching through the forums and laboriously testing all the highlight functions (as I was too lazy to write my own, I wanted a quick solution), I found that none of them did what I wanted at all.
I just wanted a function that took a string and did not modify it in anyway, apart from just surrounding the matching words with some kind of highlighting HTML. At best all the ones of the forums here changed the text but also the case as well. The example given by sawdust *did* work except when given a single character when it continued to loop-replace the letter 'a' in the inserted 'background-color:'. So, here is a fool proof, no-nonsense replace method that should work always.
<?php
function highlight($haystack, $needle) {
if (strlen($haystack) < 1 || strlen($needle) < 1) {return $haystack;}
preg_match_all("/$needle+/i", $haystack, $match);
$exploded = preg_split("/$needle+/i",$haystack);
$replaced = "";
foreach($exploded as $e)
foreach($match as $m)
if($e!=$exploded[count($exploded)-1]) {$replaced .= $e . "<font style=\"background-color:yellow\">" . $m[0] . "</font>";} else {$replaced .= $e;}
return $replaced;
}
?>
For highlighting without the overhead of regex and without destroying capitalization, try this:
<?php
function highlight($needle, $haystack){
$ind = stripos($haystack, $needle);
$len = strlen($needle);
if($ind !== false){
return substr($haystack, 0, $ind) . "<b>" . substr($haystack, $ind, $len) . "</b>" .
highlight($needle, substr($haystack, $ind + $len));
} else return $haystack;
}
?>
This example uses HTML bold tags, but you can easily change the highlighting method.
Warning with highlighting ...
I used :
<?php
$text = preg_replace('/('.$q.')/i','<span class=highlighting "">$1</span>' , $text);
?>
Because this line do not allow to highlight uppercase and lowercase correctly (transform uppercase to lowercase for exemple)
<?php
$text = str_ireplace( $q , '<span class=highlighting "">'.$q.'</span>', $text);
?>
But when $q contain some regex you have some problems ... for exemple :
<?php $q = '('; ?>
So you must use preg_replace to highlight correctly the text and you must create a function for escape bad regex caracters !
I think that a better function can be found but this works I guess :
<?php
function regex_escape( $q )
{
return preg_replace('/([\[\]\(\)\{\}\-\.\*\?\|\^\$])/', '\$1', $q);
}
?>
FIX-ed problem with highlighting second 'o' OR 'a', in this string
<?php
function highlight_string ($haystack, $needle, $highlight_class) {
// return $haystack if there is no highlight color or strings given, nothing to do.
$first_encode='XXXXXXXXXXXXXXX'; //ENCODE string
$second_encode='YYYYYYYYYYYYYYY';
preg_match_all("/$needle+/i", $haystack, $matches);
if (is_array($matches[0]) && count($matches[0]) >= 1) {
foreach ($matches[0] as $match) {
$haystack = str_replace($match, $first_encode.$match.$second_encode, $haystack);
}
}
$haystack=str_replace(array($first_encode,$second_encode),
array('<font class="'.$highlight_class.'" >','</font>'),$haystack);
return $haystack;
}
?>
Regarding maintaining the case of the find/replace for search-highlighting purposes:
if the performance hit of a regular expression isn't a big problem, there's something like:
<?php
function highlight_matches($find_text, $text) {
return preg_replace("/($find_text)/i", '<span class="search_item">$1</span>', $text);
}
?>
If you want to keep the original capitalization when replacing some text (e.g. for highlighting the search-string in the the search result), you can use this code I wrote:
<?php
// http://devboard.viathinksoft.de/viewtopic.php?f=34&t=771
// Bugfix-Release #3 (June, 22th 2009)
function ext_str_ireplace($findme, $replacewith, $subject)
{
// Replaces $findme in $subject with $replacewith
// Ignores the case and do keep the original capitalization by using $1 in $replacewith
// Required: PHP 5
$rest = $subject;
$result = '';
while (stripos($rest, $findme) !== false) {
$pos = stripos($rest, $findme);
// Remove the wanted string from $rest and append it to $result
$result .= substr($rest, 0, $pos);
$rest = substr($rest, $pos, strlen($rest)-$pos);
// Remove the wanted string from $rest and place it correctly into $result
$result .= str_replace('$1', substr($rest, 0, strlen($findme)), $replacewith);
$rest = substr($rest, strlen($findme), strlen($rest)-strlen($findme));
}
// After the last match, append the rest
$result .= $rest;
return $result;
}
?>
For function work with cirilic
setlocale (LC_ALL, 'ru_RU');
Here's a different approach to search result keyword highlighting that will match all keyword sub strings in a case insensitive manner and preserve case in the returned text. This solution first grabs all matches within $haystack in a case insensitive manner, and the secondly loops through each of those matched sub strings and applies a case sensitive replace in $haystack. This way each unique (in terms of case) instance of $needle is operated on individually allowing a case sensitive replace to be done in order to preserve the original case of each unique instance of $needle.
<?php
function highlightStr($haystack, $needle, $highlightColorValue) {
// return $haystack if there is no highlight color or strings given, nothing to do.
if (strlen($highlightColorValue) < 1 || strlen($haystack) < 1 || strlen($needle) < 1) {
return $haystack;
}
preg_match_all("/$needle+/i", $haystack, $matches);
if (is_array($matches[0]) && count($matches[0]) >= 1) {
foreach ($matches[0] as $match) {
$haystack = str_replace($match, '<span style="background-color:'.$highlightColorValue.';">'.$match.'</span>', $haystack);
}
}
return $haystack;
}
?>
This function will highlight search terms (Key Words in Context).
The difference between this one and the ones below is that it will preserve the original case of the search term as well. So, if you search for "american" but in the original string it is "American" it will retain the capital "A" as well as the correct case for the rest of the string.
<?php
function kwic($str1,$str2) {
$kwicLen = strlen($str1);
$kwicArray = array();
$pos = 0;
$count = 0;
while($pos !== FALSE) {
$pos = stripos($str2,$str1,$pos);
if($pos !== FALSE) {
$kwicArray[$count]['kwic'] = substr($str2,$pos,$kwicLen);
$kwicArray[$count++]['pos'] = $pos;
$pos++;
}
}
for($I=count($kwicArray)-1;$I>=0;$I--) {
$kwic = '<span class="kwic">'.$kwicArray[$I]['kwic'].'</span>';
$str2 = substr_replace($str2,$kwic,$kwicArray[$I]['pos'],$kwicLen);
}
return($str2);
}
?>
Example for str_ireplace(). It will print "RePlaCeMe" in red color, but after this, it would be written in lower case because of the string $search.
<?php
$search = 'replaceme';
$replace = '<font color="#FF0000">'.$search.'</font>';
$text = 'Please RePlaCeMe, OK?';
echo str_ireplace($search, $replace, $text);
?>
Example for ext_str_ireplace(). It will print "RePlaCeMe" in red color, and will not change the capitalization:
<?php
$search = 'replaceme';
$replace = '<font color="#FF0000">$1</font>';
$text = 'Please RePlaCeMe, OK?';
echo ext_str_ireplace($search, $replace, $text);
?>
I modified a script from notes on the eregi_replace() function page. This is a highlight script that worked good for me.
$text - is the text to search
$words - are the words to highlight (search text)
$the_place - is so that you can tell your users what "area" was searched.
<?php
function highlight_this($text, $words, $the_place) {
$words = trim($words);
$wordsArray = explode(' ', $words);
foreach($wordsArray as $word) {
if(strlen(trim($word)) != 0)
$text = str_ireplace($word, "<span class=\"highlight\">".strtoupper($word)."</span>", $text, $count);
}
//added to show how many keywords were found
echo "<br><div class=\"emphasis\">A search for <strong>" . $words. "</strong> found <strong>" . $count . "</strong> matches within the " . $the_place. ".</div><br>";
//end script modification
return $text;
}
?>
Here are some minor tweaks to-n00b-at-battleofthebits-dot-org's excellent function.
1) The token was set to an ASCII value 1 (which could be changed as was previously noted)
2) The $c++ was not needed
3) The while statement is not necessary for the final replacement
4) Note that this does not allow use of arrays for search and replace terms. That could be implemented using loops.
<?php
if(!function_exists('str_ireplace')){
function str_ireplace($search,$replace,$subject){
$token = chr(1);
$haystack = strtolower($subject);
$needle = strtolower($search);
while (($pos=strpos($haystack,$needle))!==FALSE){
$subject = substr_replace($subject,$token,$pos,strlen($search));
$haystack = substr_replace($haystack,$token,$pos,strlen($search));
}
$subject = str_replace($token,$replace,$subject);
return $subject;
}
}
?>
Note that character case is being defined by your server's locale setting, which effects strings containing non-ASCII characters.
See strtolower() - http://www.php.net/strtolower and comments - internally str_ireplace converts $search and $replace to lowercase to find matches.
here's a neat little function I whipped up to do HTML color coding of SQL strings.
<?php
/**
* Output the HTML debugging string in color coded glory for a sql query
* This is very nice for being able to see many SQL queries
* @access public
* @return void. prints HTML color coded string of the input $query.
* @param string $query The SQL query to be executed.
* @author Daevid Vincent [daevid@LockdownNetworks.com]
* @version 1.0
* @date 04/05/05
* @todo highlight SQL functions.
*/
function SQL_DEBUG( $query )
{
if( $query == '' ) return 0;
global $SQL_INT;
if( !isset($SQL_INT) ) $SQL_INT = 0;
//[dv] this has to come first or you will have goofy results later.
$query = preg_replace("/['\"]([^'\"]*)['\"]/i", "'<FONT COLOR='#FF6600'>$1</FONT>'", $query, -1);
$query = str_ireplace(
array (
'*',
'SELECT ',
'UPDATE ',
'DELETE ',
'INSERT ',
'INTO',
'VALUES',
'FROM',
'LEFT',
'JOIN',
'WHERE',
'LIMIT',
'ORDER BY',
'AND',
'OR ', //[dv] note the space. otherwise you match to 'COLOR' ;-)
'DESC',
'ASC',
'ON '
),
array (
"<FONT COLOR='#FF6600'><B>*</B></FONT>",
"<FONT COLOR='#00AA00'><B>SELECT</B> </FONT>",
"<FONT COLOR='#00AA00'><B>UPDATE</B> </FONT>",
"<FONT COLOR='#00AA00'><B>DELETE</B> </FONT>",
"<FONT COLOR='#00AA00'><B>INSERT</B> </FONT>",
"<FONT COLOR='#00AA00'><B>INTO</B></FONT>",
"<FONT COLOR='#00AA00'><B>VALUES</B></FONT>",
"<FONT COLOR='#00AA00'><B>FROM</B></FONT>",
"<FONT COLOR='#00CC00'><B>LEFT</B></FONT>",
"<FONT COLOR='#00CC00'><B>JOIN</B></FONT>",
"<FONT COLOR='#00AA00'><B>WHERE</B></FONT>",
"<FONT COLOR='#AA0000'><B>LIMIT</B></FONT>",
"<FONT COLOR='#00AA00'><B>ORDER BY</B></FONT>",
"<FONT COLOR='#0000AA'><B>AND</B></FONT>",
"<FONT COLOR='#0000AA'><B>OR</B> </FONT>",
"<FONT COLOR='#0000AA'><B>DESC</B></FONT>",
"<FONT COLOR='#0000AA'><B>ASC</B></FONT>",
"<FONT COLOR='#00DD00'><B>ON</B> </FONT>"
),
$query
);
echo "<FONT COLOR='#0000FF'><B>SQL[".$SQL_INT."]:</B> ".$query."<FONT COLOR='#FF0000'>;</FONT></FONT><BR>\n";
$SQL_INT++;
} //SQL_DEBUG
?>
This functionality is now implemented in the PEAR package PHP_Compat.
More information about using this function without upgrading your version of PHP can be found on the below link:
http://pear.php.net/package/PHP_Compat
