2

Let say I have the following string which I want to send as an email to a customer.

"Hello Mr/Mrs {{Name}}. You have subscribed for {{Service}} at {{Date}}."

And I have an array with the values that should be replaced

array(
    'Name' => $customerName, //or string
    'Service' => $serviceName, //or string
    'Date' => '2015-06-06'
);

I can find all strings between {{..}} with this:

preg_match_all('/\{{(.*?)\}}/',$a,$match);

where $match is an array with values, But I need to replace every match with a corresponding value from an array with values

Note that the array with values contains a lot more values and the number of items in it or the keys sequence is not relevant to number of matches in string.

1
  • As an alternative you can use an existing template engine which already does this. Or use a library that sends mail and accepts variables of the sort. Commented Dec 1, 2015 at 12:15

3 Answers 3

3

You can use preg_replace_callback and pass the array with the help of use to the callback function:

$s = "Hello Mr/Mrs {{Name}}. You have subscribed for {{Service}} at {{Date}} {{I_DONT_KNOW_IT}}.";
$arr = array(
    'Name' => "customerName", //or string
    'Service' => "serviceName", //or string
    'Date' => '2015-06-06'
);
echo $res = preg_replace_callback('/{{(.*?)}}/', function($m) use ($arr) {
       return isset($arr[$m[1]]) ? $arr[$m[1]] : $m[0]; // If the key is uknown, just use the match value
    }, $s);
// => Hello Mr/Mrs customerName. You have subscribed for serviceName at 2015-06-06.

See IDEONE demo.

The $m[1] refers to what has been captured by the (.*?). I guess this pattern is sufficient for the current scenario (does not need unrolling as the strings it matches are relatively short).

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you. This is what i was looking for.
I'd suggest return isset($arr[$m[1]]) ? $arr[$m[1]] : ''; in case there are some tags not registered in the dictionary.
@Amarnasan: Yes, a good suggestion. If the expected behavior is to just remove unknown tags, this will work. Ivo, please check if this is the expected behavior, and I will update the answer accordingly.
Yes I implemented that of course. Even I made it like this: return isset($arr[$m[1]]) ? $arr[$m[1]] : '{{'.$m[1].'}}'; So if there is no match it will return the {{key}} to be known that the given key is not proper
I suggest just using $m[0] that stands for the whole matched text. In the example string, I added {{I_DONT_KNOW_IT}}, and it is output as is since there is no corresponding key in the dictionary.
1

You don't need to use a regex for that, you can do it with a simple replacement function if you change a little the array keys:

$corr = array(
    'Name' => $customerName, //or string
    'Service' => $serviceName, //or string
    'Date' => '2015-06-06'
);

$new_keys = array_map(function($i) { return '{{' . $i . '}}';}, array_keys($corr));
$trans = array_combine($new_keys, $corr);

$result = strtr($yourstring, $trans);

Comments

1

Try

<?php

$str = "Hello Mr/Mrs {{Name}}. You have subscribed for {{Service}} at {{Date}}.";

$arr = array(
    'Name' => 'some Cust', //or string
    'Service' => 'Some Service', //or string
    'Date' => '2015-06-06'
);

$replaceKeys = array_map(
   function ($el) {
      return "{{{$el}}}";
   },
   array_keys($arr)
);

$str = str_replace($replaceKeys, array_values($arr), $str);

echo $str;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.