延迟模板字符串插值 [英] Deferred template string interpolation
问题描述
在C#中,有这样的字符串插值支持:
In C# there is a string interpolation support like this:
$"Constant with {Value}"
它将使用范围内变量 Value
格式化该字符串.
which will format this string using in-scope variable Value
.
但是以下内容无法在当前的C#语法中进行编译.
But the following won't compile in current C# syntax.
说,我有一个静态的 Dictionary< string,string>
模板:
Say, I have a static Dictionary<string, string>
of templates:
templates = new Dictionary<string, string>
{
{ "Key1", $"{Value1}" },
{ "Key2", $"Constant with {Value2}" }
}
然后在每次运行此方法时,我都要填写占位符:
And then on every run of this method I want to fill in the placeholders:
public IDictionary<string, string> FillTemplate(IDictionary<string, string> placeholderValues)
{
return templates.ToDictionary(
t => t.Key,
t => string.FormatByNames(t.Value, placeholderValues));
}
在不执行那些占位符的Regex解析然后对该Regex进行替换回调的情况下是否可以实现?哪种方法最适合作为热路径?
Is it achievable without implementing Regex parsing of those placeholders and then a replace callback on that Regex? What are the most performant options that can suit this method as being a hot path?
例如,可以在Python中轻松实现:
For example, it is easily achievable in Python:
>>> templates = { "Key1": "{Value1}", "Key2": "Constant with {Value2}" }
>>> values = { "Value1": "1", "Value2": "example 2" }
>>> result = dict(((k, v.format(**values)) for k, v in templates.items()))
>>> result
{'Key2': 'Constant with example 2', 'Key1': '1'}
>>> values2 = { "Value1": "another", "Value2": "different" }
>>> result2 = dict(((k, v.format(**values2)) for k, v in templates.items()))
>>> result2
{'Key2': 'Constant with different', 'Key1': 'another'}
推荐答案
使用基于正则表达式进行替换的扩展方法,对于每个调用多个 Replace
调用,我获得了更快的速度值.
Using an extension method that does a substitution based on regular expressions, I get a good speed up over using multiple Replace
calls for each value.
这是我的扩展方法,用于扩展大括号包围的变量:
Here is my extension method for expanding brace surrounded variables:
public static class ExpandExt {
static Regex varPattern = new Regex(@"{(?<var>\w+)}", RegexOptions.Compiled);
public static string Expand(this string src, Dictionary<string, string> vals) => varPattern.Replace(src, m => vals.TryGetValue(m.Groups[1].Value, out var v) ? v : m.Value);
}
这是使用它的示例代码:
And here is the sample code using it:
var ans = templates.ToDictionary(kv => kv.Key, kv => kv.Value.Expand(values));
在18个条目上使用 values
进行了10,000次以上的重复扩展,通常只有一次替换,与多个 String.Replace
调用相比,我得到的速度快3倍.
Over 10,000 repeating expansions with values
at 18 entries and typically only one replacement, I get 3x faster than multiple String.Replace
calls.
这篇关于延迟模板字符串插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!