Question

I am building a very simple email templating system in C#, and it works amazingly, but I have a personal issue with the way I designed it:

Template looks like this:

Hello {UserName},
Welcome to ....

And the way I am replacing the tokens with values is this:

foreach (var variable in variables)
{
    str = str.Replace("{" + variable.Key + "}", variable.Value);
}

Well, to say the least, I hate it. Is there any more efficient way of dealing with tokens?

UPDATE: Found this article, and looks like both REGEX and StringBuilder are slower than String.Replace();

StringBuilder.Replace VS REGEX.Replace vs String.Replacte

Was it helpful?

Solution

I don't think you need tokens.

One possible way to improve things is to look at each character in input the text (the templates) only once.

Search through the string from start to finish (once), and assemble a new string as follows: from the start, search for {, followed by identifier characters, then }. Move the string text before the { to the new string, then look up the identifier in a dictionary and move the replacement to the new string. Start over looking for { from where you left off last.

This way you're not scanning the input text over and over. You could tokenize the input string, but I don't think it helps compared to this suggestion.

The point here is to think about how things scale (think O() descriptions). If some template is very large then you're scanning that text once for each str.Replace operation. Further, if the number of variables is very large, then you're scanning a large input text as many times as the number of variables. With this suggestion, you scan the input text only once, no matter how many variables.

OTHER TIPS

Another way to solve this is using regular expressions:

string LookupVariable(Match match) {
   string name = match.Groups[1].Value;
   return variables[name];
}

str = (new Regex("{([^}]*)}")).Replace(str, LookupVariable);

I don't actually code C#, so my syntax is almost certainly not quite right.

Licensed under: CC-BY-SA with attribution
scroll top