views:

468

answers:

4

For some reason I'm struggling with this.

I have the following 2 arrays and I need to take the array values from the $img array and insert them in order into the $text array, appending/replacing the %img_ tags, like so:

$text = array(
    0 => "Bunch of text %img_ %img_: Some more text blabla %img_",
    1 => "More text %img_ blabla %img_"
);

$img = array("BLACK","GREEN","BLUE", "RED", "PINK");

I want my $text array to end up like so:

$text = array(
    0 => "Bunch of text %img_BLACK %img_GREEN: Some moretext blabla %img_BLUE",
    1 => "More text %img_RED blabla %img_PINK"
);

NOTE: The number of items in the $img array will vary but will always be the same as the number of %img_ in the $text array.

+5  A: 

Here's one way you could do it, using preg_replace_callback with a class to wrap up the details of tracking which replacement string in your $img array to use:

class Replacer
{
    public function __construct($img)
    {
       $this->img=$img;
    }

    private function callback($str)
    {
        //this function must return the replacement string
        //for each match - we simply cycle through the 
        //available elements of $this->img.

        return '%img_'.$this->img[$this->imgIndex++];
    }

    public function replace(&$array)
    {
        $this->imgIndex=0;

        foreach($array as $idx=>$str)
        {
            $array[$idx]=preg_replace_callback(
               '/%img_/', 
               array($this, 'callback'), 
               $str);
        }
    } 
}

//here's how you would use it with your given data
$r=new Replacer($img);
$r->replace($text);
Paul Dixon
nice to see some OO solutions around here :)
Mark
Ahh, thanks Paul. Beautifully done! Saved me a bunch of head scratching.
k00k
+1  A: 

OOP is good. Here is my non-OOP one :D

$text = array(
    0 => "Bunch of text %img_ %img_: Some more text blabla %img_",
    1 => "More text %img_ blabla %img_"
);

$img = array("BLACK","GREEN","BLUE", "RED", "PINK");

$newtext = array();
$k = 0;
for($i = 0; $i < count($text); $i++) {
    $texts = split("%img_", $text[$i]);
    $jtext = $texts[0];
    for($j = 1; $j < count($texts); $j++) {
     $jtext .= "%img_";
     $jtext .= $img[$k++];
     $jtext .= $texts[$j];
    }
    $newtext[] = "$jtext\n";
}

print_r($newtext);

You can group that to a function if you like.

Hope this helps.

NawaMan
Also useful NawaMan, thanks.
k00k
+1  A: 

Here's yet another way:

<?php

$text = array(
    0 => "Bunch of text %img_ %img_: Some more text blabla %img_",
    1 => "More text %img_ blabla %img_"
);

$img = array("BLACK","GREEN","BLUE", "RED", "PINK");

foreach ($text as &$row) {
        $row = str_replace("%img_", "%%img_%s", $row);
        $row = vsprintf($row, $img);
}

print_r($text);

Which outputs:

Array
(
    [0] => Bunch of text %img_BLACK %img_GREEN: Some more text blabla %img_BLUE
    [1] => More text %img_BLACK blabla %img_GREEN
)
Emil H
+2  A: 

Another version for php 5.3+ using an anonymous function and some spl:

$text = array(
  "Bunch of text %img_ %img_: Some more text blabla %img_",
  "More text %img_ blabla %img_"
);
$img = new ArrayIterator(array("BLACK","GREEN","BLUE", "RED", "PINK"));
foreach($text as &$t) {
  $t = preg_replace_callback('/%img_/', function($s) use($img) {
      $rv = '%img_' . $img->current();
      $img->next();
      return $rv;
    }, $t);
}

var_dump($text);
VolkerK
This is similar to how I initially attacked the problem. Thanks for this VolkerK.
k00k