Date: 2007nov28
Updated: 2010nov25
Updated: 2016may11
Language: javaScript, Perl, C
Keywords: template
Q. How would you replace $variables in some text?
A. I'll give you the answer in 3 languages.
In javaScript:
function replaceDollarVariables(txt, h) {
const re = /\$(\w+)/;
let match;
while (match = re.exec(txt)) {
txt = txt.replace(match[0], h[match[1]]);
}
return txt;
}
function exampleUse() {
const h = { person: 'Joe' };
const txt = replaceDollarVariables('hello $person, how are you?', h);
console.log('replaced=' + txt);
}
In Perl:
sub main() {
my($buf, %val);
$buf = 'hello $person, how are you?';
$val{person} = 'Joe';
$buf =~ s/\$(\w+)/$val{$1}/eg;
# The e is key here. It means the replacement value is executed.
# By the way, don't use eval().
# - it does too much - you'll have to quotemeta everything before and
# then unquote it somehow after.
# - you don't want to eval() untrusted stuff that might come from a web user!
print "Result: $buf\n";
}
In C:
While not totally bulletproof, this function does the trick.
// First, a small helper function
inline char *Shuffle(char *dest, const char *src)
{
return (char *) memmove(dest, src, strlen(src) + sizeof(char));
}
/*
parameters:
buf: A NUL-terminated buffer that may or may not contain a dollar variable
eg "hello $person, how are you""
size: Size of buf in bytes.
szVar: The name of the variable to replace. "person" in this example.
szVal: The new value for the variable. eg "Joe".
If the size of this new value is larger the size allocated for buf
we'll have a buffer overflow. So don't allow szVal from untrusted
users.
*/
void ReplaceDollarVariable(char *buf, const size_t size, const char *szVar, const char *szVal)
{
char * p = buf;
size_t lenVar = lstrlen(szVar);
size_t lenThisVar;
size_t n = lstrlen(buf);
size_t lenVal = lstrlen(szVal);
while ((p = strchr(buf, '$')) != NULL)
{
lenThisVar = strspn(p+1, "abcdefghijklmonpqrstuvwxyz");
if (lenThisVar == lenVar && strncmp(szVar, p+1, lenThisVar) == 0)
{
n += lenVal - (1+lenThisVar);
if (n > size) break;
Shuffle(p+lenVal, p+1+lenThisVar);
memcpy(p, szVal, lenVal);
p += lenVal;
}
}
}
// Example use:
void main()
{
char buf[1024] = "Hello $person, how are you?";
ReplaceDollarVariable(buf, "person", "Joe");
printf("Result: %s\n", buf);
}
If you want a full-fledged templating system, check out:
http://code.google.com/p/google-ctemplate
And there are many others.