模板引擎实现

3
我正在构建一个小型模板引擎。它需要一个包含模板的字符串参数和一个“标签,值”字典来填充模板。
在引擎中,我不知道哪些标签会出现在模板中,哪些不会。
目前,我正在对字典进行迭代(foreach),将我的字符串放入字符串生成器中,并通过替换模板中的标签为其相应的值来解析它。
有没有更有效/方便的方法来做到这一点呢?我知道主要缺点在于每个标签都要针对整个字符串生成器进行解析,这是相当糟糕的...
(尽管未在示例中包含)我还检查了一下,在处理之后,我的模板不再包含任何标签。它们都以相同的方式格式化:@@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();

回复:

@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");

输出: "value2模板中的一些文本"

而不是: "value2模板中的一些@@foobar@@文本"


好的...使用Dictionary<string,string>代替StringDictionary,它会在缺失键时抛出错误...不难。 - Marc Gravell
3个回答

1

使用正则表达式和MatchEvaluator怎么样?像这样:

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];
});

一旦模式出错(例如另一个@放错位置),它就变得完全无用了。除非有人有更好的解决方案,否则我会坚持使用我的替换方法... - qwerty
编辑:实际上,如果你有像这样的标签 @@foo2 bar@@,它是没有用的。如果在模板中有类似 @@foo bar@@ 的内容,它将被替换为一个空格。这对于错误检测来说是一个糟糕的解决方案。 - qwerty
你能详细说明一下这两点吗?“foo bar” 应该还是可以正常工作的...而且我也不明白你所说的“另一个@错位”的意思。有例子吗? - Marc Gravell

0

这里是你可以用作起点的示例代码:

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);
    }
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接