2

I've researched and need to find the best way to replace a need with an array of possibilities randomly.

ie:

$text = "Welcome to [city]. I want [city] to be a random version each time. [city] should not be the same [city] each time.";

$keyword = "[city]";
$values = array("Orlando", "Dallas", "Atlanta", "Detroit", "Tampa", "Miami");

$result = str_replace("[$keyword]", $values, $text);

The result is every occurrence has "Array" for city. I need to replace all of the city occurrences with a random from $values. I want to do this the cleanest way possible. My solution so far is terrible (recursive). What is the best solution for this? Thank you!

Paul
  • 135,475
  • 25
  • 268
  • 257
Kris B.
  • 95
  • 1
  • 7

6 Answers6

7

You can use preg_replace_callback to execute a function for each match and return the replacement string:

$text = "Welcome to [city]. I want [city] to be a random version each time. [city] should not be the same [city] each time.";

$keyword = "[city]";
$values = array("Orlando", "Dallas", "Atlanta", "Detroit", "Tampa", "Miami");

$result = preg_replace_callback('/' . preg_quote($keyword) . '/', 
  function() use ($values){ return $values[array_rand($values)]; }, $text);

Sample $result:

Welcome to Atlanta. I want Dallas to be a random version each time. Miami should not be the same Atlanta each time.

Paul
  • 135,475
  • 25
  • 268
  • 257
  • This does not guarantee: "_should not be the same_". This solution may randomly print the same city in the same block of text. – mickmackusa Jan 03 '22 at 14:44
5

You could use preg_replace_callback with array_rand

<?php
$text = "Welcome to [city]. I want [city] to be a random version each time. [city] should not be the same [city] each time.";

$values = array("Orlando", "Dallas", "Atlanta", "Detroit", "Tampa", "Miami");

$result = preg_replace_callback("/\[city\]/", function($matches) use ($values) { return $values[array_rand($values)]; }, $text);

echo $result;

Example here.

Hamish
  • 22,072
  • 7
  • 50
  • 67
  • This does not guarantee: "_should not be the same_". This solution may randomly print the same city in the same block of text. – mickmackusa Jan 03 '22 at 14:45
1

Here's another idea

$text = "Welcome to [city]. I want [city] to be a random version each time. [city] should not be the same [city] each time.";

$pattern = "/\[city\]/";
$values = array("Orlando", "Dallas", "Atlanta", "Detroit", "Tampa", "Miami");

while(preg_match($pattern, $text)) {
        $text = preg_replace($pattern, $values[array_rand($values)], $text, 1);
}

echo $text;

And some output:

Welcome to Orlando. I want Tampa to be a random version each time. Miami should not be the same Orlando each time.
  • This does not guarantee: "_should not be the same_". This solution may randomly print the same city in the same block of text. – mickmackusa Jan 03 '22 at 14:45
0

You're replacing a text using $values which is an array, so the result is just the word "Array". The replacement should be a string.

You can use array_rand() to pick random entries from your array.

$result = str_replace($keyword, $values[array_rand($values)], $text);

The result is something like this:

Welcome to Atlanta. I want Atlanta to be a random version each time. Atlanta should not be the same Atlanta each time.
Welcome to Orlando. I want Orlando to be a random version each time. Orlando should not be the same Orlando each time.

If you want the city to be random each line, check @PaulP.R.O's answer.

flowfree
  • 16,008
  • 12
  • 48
  • 75
  • "[city] should not be the same [city] each time" – Hamish Jun 11 '12 at 02:34
  • Thanks, rour solution works great for the same replacement. However, I needed to have variable replacements in one go throughout the entire document. :) – Kris B. Jun 11 '12 at 02:43
0

If:

  1. the four city placeholders that are randomly selected should not repeat within your 3-sentence string and
  2. you don't mind mutating the input array and
  3. you will always have enough values to accommodate all of the placeholders, then:

You can pass the array into the custom function scope as a reference variable. This means that as you access and remove values via array_pop(), it will be impossible to encounter the same city twice. You only need to shuffle() the input array once before performing the replacements.

Code: (Demo)

$text = "Welcome to [city]. I want [city] to be a random version each time. [city] should not be the same [city] each time.";

$keyword = "[city]";
$values = ["Orlando", "Dallas", "Atlanta", "Detroit", "Tampa", "Miami"];
shuffle($values);

echo preg_replace_callback(
         '/' . preg_quote($keyword) . '/',
         function() use(&$values) { return array_pop($values); },
         $text
     );

Potential outputs:

Welcome to Detroit. I want Tampa to be a random version each time. Dallas should not be the same Orlando each time.

or

Welcome to Orlando. I want Miami to be a random version each time. Atlanta should not be the same Detroit each time.

or

Welcome to Atlanta. I want Tampa to be a random version each time. Orlando should not be the same Dallas each time.

etc.

mickmackusa
  • 37,596
  • 11
  • 75
  • 105
-1

try this http://codepad.org/qp7XYHe4

<?
$text = "Welcome to [city]. I want [city] to be a random version each time. [city] should not be the same [city] each time.";

$keyword = "[city]";
$values = array("Orlando", "Dallas", "Atlanta", "Detroit", "Tampa", "Miami");

echo $result = str_replace($keyword, shuffle($values)?current($values):$values[0], $text);
Pramendra Gupta
  • 14,279
  • 4
  • 32
  • 34
  • Doesn't work, because "[city] should not be the same [city] each time". This uses the same value for each replacement. – Hamish Jun 11 '12 at 02:35