template engine implementation

只愿长相守 提交于 2019-12-22 10:33:27

问题


I am currently building this small template engine. It takes a string containing the template in parameter, and a dictionary of "tags,values" to fill in the template.

In the engine, I have no idea of the tags that will be in the template and the ones that won't.

I am currently iterating (foreach) on the dictionnary, parsing my string that I have put in a string builder, and replacing the tags in the template by their corresponding value.

Is there a more efficient/convenient way of doing this? I know the main drawback here is that the stringbuilder is parsed everytime entirely for each tag, which is quite bad...

(I am also checking, though not included in the sample, after the process that my template does not contain any tag anymore. They are all formated in the same way: @@tag@@)

//Dictionary<string, string> tagsValueCorrespondence;
//string template;

StringBuilder outputBuilder = new StringBuilder(template);
foreach (string tag in tagsValueCorrespondence.Keys)
{
    outputBuilder.Replace(tag, tagsValueCorrespondence[tag]);
}

template = outputBuilder.ToString();

Responses:

@Marc:

string template = "Some @@foobar@@ text in a @@bar@@ template";
StringDictionary data = new StringDictionary();
data.Add("foo", "value1");
data.Add("bar", "value2");
data.Add("foo2bar", "value3");

Output: "Some text in a value2 template"

instead of: "Some @@foobar@@ text in a value2 template"


回答1:


How about a Regex and MatchEvaluator? Like so:

string template = "Some @@Foo@@ text in a @@Bar@@ template";
StringDictionary data = new StringDictionary();
data.Add("foo", "random");
data.Add("bar", "regex");
string result = Regex.Replace(template, @"@@([^@]+)@@", delegate(Match match)
{
    string key = match.Groups[1].Value;
    return data[key];
});



回答2:


Here is sample code you can use as starting point:

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

class Program {
    static void Main() {
        var template = " @@3@@  @@2@@ @@__@@ @@Test ZZ@@";
        var replacement = new Dictionary<string, string> {
                {"1", "Value 1"},
                {"2", "Value 2"},
                {"Test ZZ", "Value 3"},
            };
        var r = new Regex("@@(?<name>.+?)@@");
        var result = r.Replace(template, m => {
            var key = m.Groups["name"].Value;
            string val;
            if (replacement.TryGetValue(key, out val))
                return val;
            else
                return m.Value;
        });
        Console.WriteLine(result);
    }
}



回答3:


You could modify the mono string format implementation into accepting your stringdictionary. For instance http://github.com/wallymathieu/cscommon/blob/master/library/StringUtils.cs



来源:https://stackoverflow.com/questions/916099/template-engine-implementation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!