Styling multiple $needles in $haystack with str_replace()

The problem: I’m trying to style every instance of a string, for each string value in an array, in a particular piece of content. I’m committed to solving this via PHP.

What I’ve tried: I think I’m close, but my loop isn’t getting me the results I need. The $needle is an array of strings. I’ve been trying to use str_replace() then run that output against the next string in the array. And loop that until all strings have been given the appropriate styling tags. But I haven’t been able to figure it out so I’ve shared my latest working code.

The output: It shows the proper styling applied to the correct strings, except that I’m getting 4x outputs. I know this is because the loop is running four times, but I can’t figure out how get a single output with all strings properly styled.

Thanks in advance for any thought on this one :pray:

// Add style to each instance of $needle found in $haystack
function add_highlight( ) {
    $needles = ['Alpha','Quebec','Whiskey','Charlie'];
    $haystack = "Alpha, Bravo, Charlie, Foxtrot, Quebec, Tango, Whiskey";

    foreach ( $needles as $needle ) {
        $new_needle = '<span style="background-color:yellow">' . $needle . '</span>';
        $new_haystack = str_replace($needle, $new_needle, $haystack);
        echo $new_haystack . '<br/>';
    }
        
}

Well first of all, don’t print on each iteration of the loop. Second you want to replace the string in the same string on each iteration. Right now you are creating a new string built from the replacement on the original string rather than built from the replacement of the previously replaced string. Try this as an example to work from…

function add_highlight( ) {
    $needles = ['Alpha','Quebec','Whiskey','Charlie'];
    $haystack = "Alpha, Bravo, Charlie, Foxtrot, Quebec, Tango, Whiskey";

    foreach ( $needles as $needle ) {
        $new_needle = '<span style="background-color:yellow">' . $needle . '</span>';
        // Notice we replace on $haystack and then put that back into $haystack
        $haystack = str_replace($needle, $new_needle, $haystack);
    }
    
    // Echo here to prevent 4x output
    echo $haystack; 
}

By using this approach you will be much closer to the desired output. One thing to watch for is that you don’t have duplicate needs otherwise you will see spans inside of spans as it will attempt to add spans to needles that are already inside other replacements made earlier.

:slight_smile:

1 Like

@editedit,

Try this:

// Add style to each instance of $needle found in $haystack
function jb_add_highlight( )
{
  $old   = ['Alpha', 'Quebec', 'Whiskey','Charlie'];
	  foreach($old as $tmp) :
	  	$new[] = '<b style="background-color:aqua">' .$tmp .'</b>';
	  endforeach;	

  echo '<pre>$old ==> ' .print_r($old, TRUE) .'</pre>';

  echo '$haystack ==> ',
  	$haystack = "Alpha, Bravo, Charlie, Foxtrot, Quebec, Tango, Whiskey";

  echo '<br><br> $new_haystack ==> ',
  	$new_haystack = str_replace($old, $new, $haystack);
}//

Output

Thanks for this @Martyr2. I did put the echo where you suggest several times before posting this question depending on the tactics. In the end, putting it inside the loop gives a stronger visual of the problem.

And really great point about having to be careful about adding multiple spans if I am recycling the haystack!

Appreciate the feedback!

Thanks for the feedback here @John_Betong!

Defining a new array with replaced values is something my brain couldn’t get to. I’m going to give this a try later tonight and let you know. Thanks for the fast response!

Hey @John_Betong - Following up. This works great. Exactly what I needed. Thanks for taking the time to lay that out. It makes 100% sense now that I’m seeing the creation of an array to replace the old array. Have a great day!

1 Like

Your next mission… use and test the foreach $key value and the modulus $key to test and change highlight colors from an array of colours [‘red’, ‘green’, ‘blue’, ‘orange’, ‘’pink’, ‘etc’].

I’m on a tablet at the moment and if you get stuck will supply a solution tomorrow.

Here we go:

//=========================
function add_highlight_colors() {
    $needles = ['Alpha','Quebec','Whiskey','Charlie'];
    $haystack = 'Alpha, Bravo, Charlie, Foxtrot, Quebec, Tango, Whiskey';

	$aClrs 	 = [
				 'background-color: red;   color: snow;', 
				 'background-color: green; color: snow; font-size: xx-large;', 
				 'background-color: blue;  color: snow;', 
				 'background-color: orange;color: blue; font-size: xx-small;', 
				 'background-color: pink;  color: snow;', 
				 'background-color: lime;  color: snow;'
				];
	$modulus = count($aClrs); # prevent $key not found
    foreach ( $needles as $key => $needle ) {
    	$new_needle = '<span style="' .$aClrs[$key % $modulus] .'">' . $needle . '</span>';
        # $new_needle = '<span style="background-color:yellow">' . $needle . '</span>';

        # Notice we replace on $haystack and then put that back into $haystack
        $haystack = str_replace($needle, $new_needle, $haystack);
    }
    
    # echo here to prevent 4x output
    echo $haystack; 
}//

Results:

Screenshot from 2021-09-10 10-34-59

Oh that’s awesome!! Thank you for this. As soon as I get into the styling, I’ll give this a go. This jumps me further ahead than where I’m at, but generating custom styling tags was something I was curious about anyway as well so this is perfect!! I’ll follow up if I have more q’s on this as I get into it! Thanks again @John_Betong!

1 Like