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

1
  • Ultimately, I'd refactor this whole task and leverage vprintf(). Commented Jul 31, 2022 at 3:08

3 Answers 3

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);
Sign up to request clarification or add additional context in comments.

2 Comments

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.
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: php.net/manual/en/function.str-replace.php
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.

3 Comments

thanks for the updates to my regex and the other helpful hints. Silly mistake really. Thanks, again.
\e modifier is deprecated as of v5.5
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.
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.

2 Comments

Thanks. I forgot about preg_replace_callback.
The i flag is useless because you have written a-zA-Z. _ doesn't need to be escaped inside of a character class.

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.