我只是写了一个简单的类。它所做的只是接受一串输入,例如
Hello @name, you look @adjective today!
并替换了 @variables
用字典中的值。例如,传入 new Dictionary<string,object>{{"name","Ralph"},{"adjective","stunning"}}
会给出:
Hello Ralph, you look stunning today!
这是类:
class Template
{
List<object> nodes = new List<object>();
public Template(string content)
{
for (int i = 0; i < content.Length; ++i)
{
char ch = content[i];
if (ch == '@')
{
var match = Regex.Match(content.Substring(i + 1), @"\w+");
if (match.Success)
{
nodes.Add(new Variable(match.Value));
i += match.Value.Length;
}
else
{
throw new Exception(string.Format("Expected variable name after @ symbol at character {0}", i));
}
}
else
{
nodes.Add(ch.ToString());
}
}
}
public string Render(Dictionary<string,object> dict)
{
var sb = new StringBuilder();
foreach (var item in nodes)
{
if (item is Variable)
{
sb.Append(dict[((Variable)item).Name]);
}
else
{
sb.Append(item);
}
}
return sb.ToString();
}
class Variable
{
public readonly string Name;
public Variable(string name)
{
Name = name;
}
}
}
这是解决此类问题的好方法吗?我想在构造函数中做尽可能多的处理,这样我就可以高效地一遍又一遍地重新呈现模板,而无需重新解析它。
现在我正在遍历整个节点列表以查找变量节点,以便我可以替换它们。也许有一种方法可以“跳”到那些节点?这会有帮助吗?
此外,我逐个字符地解析它,但随后我使用正则表达式(我想从下一个字符开始,所以我使用 .Substring 来获取字符串的其余部分)来获取“ block ”文本。我不确定在不使用正则表达式的情况下如何获得整个变量名称?
这门课会变得更加复杂,所以我想在继续之前确保我有正确的方法。
我的两个担忧是:
- 有什么好方法可以从当前位置拉出一大块文本,然后增加计数器?例如,一旦我确定下一段文本实际上应该是一个变量名,就提取变量名。
- 我应该如何存储节点(在这种情况下,只是文本和变量节点),以便以后可以快速一遍又一遍地呈现模板?
最佳答案
关于:
s = s.Replace("@name", name);
s = s.Replace("@Adjective", adjective);
此外,我会避免在解析文本时抛出异常。由于用户字符串几乎可以包含任何内容,因此最好尽可能智能地尝试和处理意外数据。
关于c# - 如何改进这个简单的模板渲染类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4632470/