Eregi_replace Loop--Must Prevent Replacing Replacements/HTML

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Arkaine
Forum Newbie
Posts: 7
Joined: Fri Jul 04, 2003 12:53 am

Eregi_replace Loop--Must Prevent Replacing Replacements/HTML

Post 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! :(
choppsta
Forum Contributor
Posts: 114
Joined: Thu Jul 03, 2003 11:11 am

Post 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!...
Arkaine
Forum Newbie
Posts: 7
Joined: Fri Jul 04, 2003 12:53 am

Post by Arkaine »

Oh my, thank you so much! You are a life saver! :)
m3rajk
DevNet Resident
Posts: 1191
Joined: Mon Jun 02, 2003 3:37 pm

Post 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.
User avatar
Stoker
Forum Regular
Posts: 782
Joined: Thu Jan 23, 2003 9:45 pm
Location: SWNY
Contact:

Post 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!
Arkaine
Forum Newbie
Posts: 7
Joined: Fri Jul 04, 2003 12:53 am

Post 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! :)
Arkaine
Forum Newbie
Posts: 7
Joined: Fri Jul 04, 2003 12:53 am

Post 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?
User avatar
Stoker
Forum Regular
Posts: 782
Joined: Thu Jan 23, 2003 9:45 pm
Location: SWNY
Contact:

Post by Stoker »

use preg_replace ()
m3rajk
DevNet Resident
Posts: 1191
Joined: Mon Jun 02, 2003 3:37 pm

Post 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 */

?>
Arkaine
Forum Newbie
Posts: 7
Joined: Fri Jul 04, 2003 12:53 am

Post 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);
m3rajk
DevNet Resident
Posts: 1191
Joined: Mon Jun 02, 2003 3:37 pm

Post 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
Post Reply