Skip to content

Instantly share code, notes, and snippets.

@iNamik
Last active June 4, 2024 19:01
Show Gist options
  • Save iNamik/4147047 to your computer and use it in GitHub Desktop.
Save iNamik/4147047 to your computer and use it in GitHub Desktop.
Simple PHP Function to Replace Tags in a String (i.e. "Hello, {{there}}" => "Hello, world")
<?php
/**
* replace_tags replaces tags in the source string with data from the tags map.
* The tags are identified by being wrapped in '{{' and '}}' i.e. '{{tag}}'.
* You may also space your tags like `{{ tag }}` for better readability.
* If a tag value is not present in the tags map, it is replaced with an empty
* string.
* @param string $string A string containing 1 or more tags wrapped in '{{}}'
* @param array $tags A map of key-value pairs used to replace tags.
# Keys cannot contain whitespace (space, tab, return) or braces ('{}').
* @param force_lower if true, converts matching tags in string via strtolower()
* before checking the tags map.
* @return string The resulting string with all matching tags replaced.
*/
function replace_tags($string, $tags, $force_lower = false)
{
return preg_replace_callback('/\\{\\{\s*([^{}\s]+)\s*\}\\}/',
function($matches) use ($force_lower, $tags)
{
// NOTE : Consider using mb_strtolower if applicable to your use case
$key = $force_lower ? strtolower($matches[1]) : $matches[1];
return array_key_exists($key, $tags)
? $tags[$key]
: ''
;
}
, $string);
}
@CasperUK
Copy link

Hello,
If possible, could you please provide an example using the above code.
Thank you.

@iNamik
Copy link
Author

iNamik commented May 8, 2019

Hello,
If possible, could you please provide an example using the above code.
Thank you.

Hi @CasperUK,

Have a look at this example:

$map = array( "greeting" => "Hello", "name" => "Newman");

#
# Test with case-matching keys
#

$template = "{{greeting}}, {{name}}";

# output (working):
# Hello, Newman
echo replace_tags($template, $map);
echo "\r\n";

#
# Test with case-mismatched keys
#

$template = "{{Greeting}}, {{NAME}}";

# output (missing values):
# ,
echo replace_tags($template, $map);
echo "\r\n";

#
# Test with case-mismatched keys but $force_lower = true
#
$template = "{{Greeting}}, {{NAME}}";

# output (working):
# Hello, Newman
echo replace_tags($template, $map, true);
echo "\r\n";

Hope that helps and thank you for your interest in my Gist !

@bboyvanz
Copy link

bboyvanz commented Mar 9, 2023

This gist is working like a charm!! Thank ya for sharing

@davidpfarrell
Copy link

This gist is working like a charm!! Thank ya for sharing

Thanks ! That means a lot for code I created in 2017 :)

@ExeQue
Copy link

ExeQue commented Jun 29, 2023

The current regexp doesn't account for trailing or leading whitespace in the string. Eg. {{ foo }}will require an input of [' foo ' => 'bar'] in order to work - We needed an implementation that allows for that without causing issues.

A regexp that accounts for that could look like the following: '/{{\s*([^{}]+\S)\s*}}/' -> https://regex101.com/r/4ts83c/1

I'd also recommend using mb_strtolower if possible, if you have even the slightest chance of encountering multibyte characters (æ, ø, å, ü etc) when lower casing.

Great code otherwise! Thanks!

@iNamik
Copy link
Author

iNamik commented Jun 4, 2024

@ExeQue wrote:

A regexp that accounts for that could look like the following: '/{{\s*([^{}]+\S)\s*}}/' -> https://regex101.com/r/4ts83c/1

Thanks for the suggestion - I've updated the regex but with a slightly different take - My update doesn't expect or allow \s to exist in the tag name.

I'd also recommend using mb_strtolower if possible, if you have even the slightest chance of encountering multibyte characters (æ, ø, å, ü etc) when lower casing.

Thats good advice, but I think there's a general consensus that the mb_ functions are slower, so I decided to just add a comment for the user to decide if the change makes sense for their use case.

Great code otherwise! Thanks!

Thanks! Its fun to see this gist still getting used so long after I created it !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment