Page 1 of 1

Eregi_replace Loop--Must Prevent Replacing Replacements/HTML

Posted: Fri Jul 04, 2003 12:53 am
by Arkaine
I know that this involves a database, but the trouble is with string manipulation, not MySQL.

Here's the situation. I've created a spiffy-looking MySQL database search engine. It's supposed to highlight each keyword like google does. I'm not looking to do different colors or anything; I just want each keyword to be highlighted. So far, I've gotten it to work. I can search for as many keywords as I like with the exception of a string that is any part of the HTML with which I use to highlight it.

This is my highlight function, along with its call for one of the columns.

Code: Select all

$Record->Name = SearchHighlight($KeywordArray,"$Record->Name");

function SearchHighlight($WordArray, $BigString, $AddBef = '<font class="SearchHighlight">', $AddAft = '</font>')&#123;
	if (is_array($WordArray))&#123;
		foreach($WordArray as $Word)&#123;
			$BigString = eregi_replace($Word, $AddBef . "\\0" . $AddAft, $BigString);
		&#125;
	&#125;else&#123;
		$BigString = eregi_replace($WordArray, $AddBef . "\\0" . $AddAft, $BigString);
	&#125;
	return $BigString;
&#125;

If I search for 'mike' it will work fine, but if I search for both 'mike' and 't' it will highlight 'mike', then highlight everything with 't'...which would be what I wanted, if it didn't highlight the 't' that's part of my HTML tag.

mike
http://www.99main.com/~arkaine/misc/contacts1.gif

mike t
http://www.99main.com/~arkaine/misc/contacts2.gif

I must have spent hours scouring the internet/forums to figure out a way to ignore html tags, juggle strings, or anything. Now I've finaly given into what I told myself I'd never do...I'm posting.

Please help me! I'm at such a loss! :(

Posted: Fri Jul 04, 2003 3:52 am
by choppsta
To avoid this problem you could do something like this...

It replaces all the matched keywords with temporary placeholders, once all the keywords are done it can then replace them with the actual highlighting code...

Code: Select all

<?php
$Record->Name = SearchHighlight($KeywordArray,"$Record->Name"); 

function SearchHighlight($WordArray, $BigString, $AddBef = '<font class="SearchHighlight">', $AddAft = '</font>'){ 
	if (is_array($WordArray)){ 

		// Replace each occurance of word with a placeholder tag
		foreach($WordArray as $k => $Word){ 
			$tag = "<<$k>>";
			$BigString = eregi_replace($Word, $tag, $BigString); 
		}

		// Now substitute each tag for the appropriate word
		foreach($WordArray as $k => $Word){ 
			$tag = "<<$k>>";
			$BigString = eregi_replace($tag, $AddBef . $Word . $AddAft, $BigString); 
		}
	}
	else { 
		$BigString = eregi_replace($WordArray, $AddBef . "\\0" . $AddAft, $BigString); 
	} 
	return $BigString; 
}?>
It's probably not the most efficient way of doing it, but I'm sure the theory is right!...

Posted: Mon Jul 07, 2003 11:13 pm
by Arkaine
Oh my, thank you so much! You are a life saver! :)

Posted: Tue Jul 08, 2003 10:38 am
by m3rajk
do you store it in the db with html?

if so, parse through and remove the html with something that wont be highlighted, or appear in the text. then return the html after highlighting parsing.

Posted: Tue Jul 08, 2003 10:56 am
by Stoker
NEVER user eregi (posix regex) as it wastes a lot of resources and time, if you really need regex power use preg!
It looks to me that using regex is a waste in this case and that str_replace would do the job? Much more effecient!

Posted: Tue Jul 08, 2003 11:37 am
by Arkaine
m3rajk wrote:do you store it in the db with html?

if so, parse through and remove the html with something that wont be highlighted, or appear in the text. then return the html after highlighting parsing.
Oh, no; of course not. This is just for display purposes.
I wouldn't want HTML in the data! :)

Posted: Tue Jul 08, 2003 12:03 pm
by Arkaine
Stoker wrote:NEVER user eregi (posix regex) as it wastes a lot of resources and time, if you really need regex power use preg!
It looks to me that using regex is a waste in this case and that str_replace would do the job? Much more effecient!
Yeah, I tried str_replace, but it's case-sensitive.
str_ireplace isn't in php 4
but preg_grep...grep...that sounds familiar...ah yes, Linux. :)

Preg_grep looks like it might work, but I haven't the slightest about how to use it.
The example in the docs:

Code: Select all

// return all array elements
// containing floating point numbers
$fl_array = preg_grep ("/^(\d+)?\.\d+$/", $array);
What's with the funky string? :)
How would I get this to work in my function?

Posted: Tue Jul 08, 2003 12:44 pm
by Stoker
use preg_replace ()

Posted: Tue Jul 08, 2003 12:57 pm
by m3rajk
http://us3.php.net/manual-lookup.php?pa ... eg&lang=en
have you ever used perl before?

the oreilly book on learning it is really good. iafter that you'll prefer the perl regular expressions.

that was the case for me.

in any case, try this:

Code: Select all

<?php
/* retrieve info from db */

$user_search_pattern='''/'.$_POST['search_for'].'/i''';
$replace_pattern='<b>'.$_POST['search_for'].'</b>';

$dbinfo=preg_replace($user_search_pattern, $replace_pattern, $dbinfo);

/* add html */

/* print to screen */

?>

Posted: Wed Jul 09, 2003 6:34 pm
by Arkaine
Okay, this doesn't appear to be doing anything...am I doing something wrong?

Code: Select all

$BigString=preg_replace('''/' . $WordArray . '/i''', $AddBef . $WordArray . $AddAft, $BigString);

Posted: Thu Jul 10, 2003 1:55 pm
by m3rajk
you can't make an array. it needs to be passed a string. make word array an arrary of '/<pattern>/i' and then use ONE of them each iteration