Depending on whether you want to account for context or not, the solutions will vary.
If you plan to just match the strings as is in any context and repalce with their copies enclosed with %1% and %2%, you need to use
preg_replace("/" . implode("|", array_map(function($i) {return preg_quote($i, "/");}, $colours)) . "/", '%1%$0%2%', $string)
The regex is formed here using | OR operator and all special chars in the items in the $colours array are escaped with \ using preg_quote function. The $0 in the replacement refers to the whole match value.
If $colours are phrases with whitespaces, you would need to sort the items so that the longer strings come first:
rsort($colours, SORT_FLAG_CASE | SORT_STRING);
echo "\n" . preg_replace("/" . implode("|", array_map(function($i) {return preg_quote($i, "/");}, $colours)) . "/", '%1%$0%2%',$string);
If these $colours are simple English letter words, and you want to match them as whole words, you do not need preg_quote and you can use word boundaries, like:
preg_replace("/\b(?:" . implode('|', $colours) . ")\b/", '%1%$0%2%', $string)
To make the search case-insensitive, add i flag after last / regex delimiter in the preg_replace first argument.
See the PHP demo:
$colours = array("Red", "Blue", "Green");
$string = "There are three Red and Green walls.";
echo preg_replace("/" . implode("|", array_map(function($i) {return preg_quote($i, "/");}, $colours)) . "/", '%1%$0%2%', $string);
// => There are three %1%Red%2% and %1%Green%2% walls.
echo "\n" . preg_replace("/\b(?:" . implode('|', $colours) . ")\b/", '%1%$0%2%', $string);
// => There are three %1%Red%2% and %1%Green%2% walls.
$colours = array("Red", "Blue", "Green", "Blue jeans");
$string = "There are three Red and Green walls and Blue jeans.";
rsort($colours, SORT_FLAG_CASE | SORT_STRING);
echo "\n" . preg_replace("/" . implode("|", array_map(function($i) {return preg_quote($i, "/");}, $colours)) . "/", '%1%$0%2%',$string);
// => There are three %1%Red%2% and %1%Green%2% walls and %1%Blue jeans%2%.
%1%…%2%each.preg_replace("/\b(?:" . implode('|', $colours) . ")\b/", '%1%$0%2%', $string)? 3v4l.org/9077N