2
votes

How would I got about replacing this

Lorem ipsum random_5ac18d179707d dolor random_5ac18d179707d sit amet, consectetur random_5ac18decebd4e adipiscing elit.

with this

Lorem ipsum random_1 dolor random_1 sit amet, consectetur random_2 adipiscing elit.

What it's doing is matching all "random_xxxxxxxxxxxxx" that are the same and giving that set of like matches a count of 1. The count then gets incremented for each additional set of like matches. There could be one or many in each set.

I have the following that is very close but just not quite right:

function replace($string) {
    $i = 1;
    return preg_replace_callback('/random_\w+/', function () use (&$i) {
        return 'random_' . $i++;
    }, $string);
}

which outputs the following

Lorem ipsum random_1 dolor random_2 sit amet, consectetur random_3 adipiscing elit.

Any way to tweak that snippet above to work?

Or perhaps there's some way to get an array of unique matches using preg_match which could then be looped and replaced with a counter? Something similar to so:

$string = 'Lorem ipsum random_5ac18d179707d dolor random_5ac18d179707d sit amet, consectetur random_5ac18decebd4e adipiscing elit.';
preg_match('/random_\w+/', $string, $matches);
print_r($matches);

# to get the following array if possible?
Array
(
    [0] => random_5ac18d179707d
    [1] => random_5ac18decebd4e
)
4

4 Answers

1
votes

Your first example very nearly solve the problem. Simply use an auxiliary index to keep track of which randoms you've seen before and which ones you haven't.

function replace($string) {
    $i = 1;
    $index = array();
    return preg_replace_callback('/random_\w+/', function ($matches) use (&$i, &$index) {
        $key = $matches[0];
        if ( isset($index[$key]) ) {
            $num = $index[$key];
        } else {
            $num = $i++;
            $index[$key] = $num;
        }
        return 'random_' . $num;
    }, $string);
}

Since $matches[0] contains the exact string matched, we use that value to lookup into an index. If the key exists in the index, we use the existing value for the number. If not, we assign a new one.

0
votes
 $strings = explode($input," ");
 $outs = array();
 $last = "";
 for ($strings as $i){
     if(!$outs[$i]){
      $outs[$i] = count($outs)+1;
     }
 }
 for ($outs as $key=>$val){
   $input = str_replace($input,$key,"random".$val);
 }
0
votes

Just another solution

$string = 'Lorem ipsum random_5ac18d179707d dolor random_5ac18d179707d sit amet, consectetur random_5ac18decebd4e adipiscing elit.';

preg_match_all('/random_(\w+)/', $string, $matches);

$replace = array_values(array_unique($matches[1]));
array_unshift($replace, null);

echo str_replace(array_values($replace), array_keys($replace), $string);
0
votes

You can do this alternatively:

preg_match_all('~random_(\w+)~', $string, $m);
echo strtr($string, array_combine($s = array_unique($m[1]), range(1, count($s))));

Live demo

If you think \w+ part may occur some where not following random_ you need to modify above code a bit:

preg_match_all('~random_\w+~', $string, $m);
echo strtr($string, array_combine($s = array_unique($m[0]), preg_filter('~^~', 'random_', range(1, count($s)))));