Forum Moderators: coopster

Message Too Old, No Replies

replace percentage of keywords in a string

I'd like to replace 1 of every 4 instances of a keyword...

         

distorto

3:16 pm on Jul 11, 2007 (gmt 0)

10+ Year Member



I'm trying to write something that replaces a percentage of keywords in html pages with links.
I have something working that will replace keywords with an array of replacement terms...and something else that turns the html pages into strings.
let's say this is the text
"I want to go to the store and from there I want to get some coffee. After that I want to make iced coffee and then I'll make some more coffee"
to replace 1 out of 4 instances of "want" with "need", I first search the document for all instances of "want". I count the instances...in this case, it's 3. so my array would be
array = 'need', 'want', 'want'
then it replaces the first instance with "need" and replaces both of the other instances with "want", which is what they started out as...so it actually appears that we've only replaced one of them.
Is there a better way to do this? I feel like there must be, but I have read everything I could find relating to string functions. I guess I feel like there must be a "smart" find/replace string function or library. Does anyone know of anything I might try? Is this something that would be very simple using regular expressions? I thought at first that it was a regex problem, but then couldn't find a simple solution.
Incidentally, the buggiest aspect of this so far is creating the array of replacement terms.

eelixduppy

4:02 pm on Jul 11, 2007 (gmt 0)



Try something like this:
[pre]
$string = "I want to go to the store and from there I want to get some coffee.
After that I want to make iced coffee and then I'll make some more coffee.";
#
#1 out of x (where x is $num) just note that it replaces the last instance (every 3rd in this case)
$num = 3;
#
$from = 'want';
$to = 'need';
#
$count = 1;
function callback($matches) {
global $num;
global $count;
global $to;
#
if($count == $num) {
$count = 1;
return $to;
} else {
$count++;
return $matches[0];
}
}
#
$pattern = "/".[url=http://www.php.net/preg-quote]preg_quote[/url]($from)."/i";
echo [url=http://www.php.net/preg-replace-callback]preg_replace_callback[/url]($pattern,'callback',$string);
[/pre]

Good luck :)

distorto

4:32 pm on Jul 11, 2007 (gmt 0)

10+ Year Member



I think I get this...
so the function "preg_replace_callback" swaps what the function callback() returns in $string keyword by keyword (as it works its way through the string from top to bottom)? If so, this is exactly the function I was searching for!
One question - what about null values? In the php.net documentation, there's some cryptic advice -
"preg_replace_callback returns NULL when pcre.backtrack_limit is reached; this sometimes occurs faster then you might expect. No error is raised either; so don't forget to check for NULL yourself"
that I don't understand.
This is a much better solution than my array based sol. Thanks so much! I will try it out after lunch.
I wish I could offer more advice to users on this forum. I really appreciate all the help I've received from this site.

eelixduppy

5:28 am on Jul 12, 2007 (gmt 0)



I've never run into the problem where the limit was reached so I cannot really give advice on how to handle it if it does. I don't think you'll have anything to worry about. I guess you can experiment.

>>I wish I could offer more advice to users on this forum.

Learn as much as you can now and give back what you can later. It doesn't have to happen all at once :)