Skip to content

Instantly share code, notes, and snippets.

@rofr
Created May 4, 2012 09:01
Show Gist options
  • Save rofr/2593447 to your computer and use it in GitHub Desktop.
Save rofr/2593447 to your computer and use it in GitHub Desktop.
Simple regex based string templating
class Program
{
static void Main(string[] args)
{
Template t = new Template("My {pet} {name} has fleas");
string[] keys = {"dog", "name"};
IEnumerable<string> missing, unrecognized;
bool isValid = t.Validate(keys, out missing, out unrecognized);
Console.WriteLine("Is valid: " + isValid);
foreach (string key in unrecognized)
{
Console.WriteLine("Unrecognized: " + key);
}
foreach (string key in missing)
{
Console.WriteLine("Missing: " + key);
}
var templateArgs = new Dictionary<string, object> {{"pet", "dog"}, {"name", "spot"}};
Console.WriteLine(t.Render(templateArgs));
Console.ReadLine();
}
}
public class Template
{
public readonly string Body;
private HashSet<string> _keys;
public const string KeyExpression = @"{(?<key>[^}]+)}";
public Template(string body)
{
Body = body;
//Extract all the keys to a hashset
_keys = new HashSet<string>();
Regex.Replace(Body, KeyExpression, k => {
_keys.Add(k.Groups["key"].Value);
return "";
});
}
public bool Validate(IEnumerable<string> keys, out IEnumerable<string> missing, out IEnumerable<string> unrecognized)
{
keys = keys.ToArray();
unrecognized = _keys.Except(keys).ToArray();
missing = keys.Except(_keys).ToArray();
return unrecognized.Count() + missing.Count() == 0;
}
public string Render(IDictionary<string,object> args)
{
return Regex.Replace(Body, KeyExpression, m => Replace(m, args));
}
private string Replace(Match match, IDictionary<string,object> args)
{
string key = match.Groups["key"].Value;
string result = "{" + key + "}";
if (args.ContainsKey(key)) result = args[key].ToString();
return result;
}
public static Template LoadFromFile(string path)
{
string body = File.ReadAllText(path);
return new Template(body);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment