4

I have an array:

array('id' => 'really')

I have a string:

$string = 'This should be {id} simple.';

I want to end up with:

This should be really simple.

I have a regular expression that will work with the {id} aspect, but I am having a hard time doing what I want.

/{([a-zA-Z\_\-]*?)}/i

{id} could be anything, {foo} or {bar} or anything that matches my regular expression.

I am sure that there is a simple solution that is escaping me at the moment.

Thanks,

Justin

manumoomoo
  • 2,707
  • 3
  • 24
  • 25

3 Answers3

4

str_replace is faster then preg_replace, try this:

$arr = array('a' => 'a', 'b' => 'b');
$str = "{a} {b} {c}";
$values = array_values($arr);
$keys = array_keys($arr);

foreach ($keys as $k => $v) {
    $keys[$k] = '{'.$v.'}';
}

str_replace($keys, $values, $str);
kodeart
  • 1,903
  • 1
  • 19
  • 27
Stuck
  • 11,225
  • 11
  • 59
  • 104
  • 1
    This is true, but $arr (in your example) could have 100's of key/value pairs, I wonder if your solution would still be faster. Thanks. – manumoomoo Dec 16 '10 at 03:22
  • maybe you can build the $arr in a way that it directly contains the '{' and '}? then you don't need the extra loop. But anyway.. it's still O(n) ;-) If you don't need fancy replacing rules , you should always use this function instead of ereg_replace() or preg_replace(). see: http://php.net/manual/en/function.str-replace.php – Stuck Dec 16 '10 at 03:25
4

You can use the preg_replace with e modifier as:

$string = preg_replace('/{([a-zA-Z\_\-]*?)}/ie','$arr["$1"]',$string);

Ideone Link

Using the e modifier you can have any PHP expression in the replacement part of preg_replace.

Now why did your regex /{([a-zA-Z\_\-])*?}/i not work?

You've put *? outside the capturing parenthesis ( ) as a result you capture only the first character of the word found in { }.

Also note that you've not escaped { and } which are regex meta-character used for specifying range quantifier {num}, {min,max}. But in your case there is no need to escape them because the regex engine can infer from the context that { and } cannot be used as range operator as they are not having numbers in required format inside them and hence treats them literally.

codaddict
  • 445,704
  • 82
  • 492
  • 529
  • thanks for the updates to my regex and the other helpful hints. Silly mistake really. Thanks, again. – manumoomoo Dec 16 '10 at 04:16
  • \e modifier is [deprecated](http://php.net/manual/en/reference.pcre.pattern.modifiers.php) as of v5.5 – kodeart Feb 05 '14 at 20:11
  • Please update this unusable snippet. `e` doesn't work. `i` doesn't make sense. Underscores don't need to be escaped in a character class. The ideone links is dead. – mickmackusa Jul 31 '22 at 03:07
1

preg_replace_callback has a callback option which make that kind of things possible.

function replaceText($matches){
  global $data;
  return $data[$matches[1]];
}
preg_replace_callback(
        '/{([a-zA-Z\_\-])*?}/i',
        'replaceText',
        $content
);

If you don't want to use the global variable create an class and use the array($object, 'method') callback notation.

Community
  • 1
  • 1
RageZ
  • 26,800
  • 12
  • 67
  • 76