鉴于我有一个存储在我的数据库中的元数据资源字符串将返回如下:
var pageTitle = "Shop the latest {category1} Designer {category2} {category3} at www.abc.com";
我希望将{placeholders}
替换为变量values
;
var category1 = "womenswear";
var category2 = "dresses";
var category3 = "cocktail dresses";
我试过,没有运气;
var newTitle = $"pageTitle, category1, category2, category3";
var newTitle = $(pageTitle, category1, category2, category3);
我知道我可以使用具有性能开销的string.Replace()
。有谁知道如何使用最新的C#字符串插值有效地完成这项工作?
答案 0 :(得分:19)
您无法在此处使用字符串插值。字符串插值是string.Format
的编译时重写方法,这是您应该使用的解决方案:
var newTitle = string.Format("{0}, {1}, {2}, {3}", pageTitle, category1, category2, category3);
或string.Join
:
var newTitle - string.Join(", ", new string[] { pageTitle, category1, category2, category3 });
由于您是从数据库加载的,因此继续使用string.Replace
可能会更好。
答案 1 :(得分:18)
我知道我可以使用性能开销
的string.Replace()
仅为纳秒。你不应该过早地进行优化。
如上所述,C#6字符串插值功能在编译时发生。如果要在运行时执行此操作,则必须使用字符串替换。
我认为你的字符串格式是这样的,以便于编辑,没有固定的替换顺序,所以只需这样做:
var input = "Shop the latest {category1} Designer {category2} {category3} at www.abc.com";
var category1 = "womenswear";
var category2 = "dresses";
var category3 = "cocktail dresses";
var result = input.Replace("{category1}", category1)
.Replace("{category2}", category2)
.Replace("{category3}", category3);
这将起作用。您还可以将替换值存储在字典中,并循环键以使用值替换键。
答案 2 :(得分:8)
尽管.NET没有为此提供内置功能,但您可以使用正则表达式轻松构建一个非常好的实现:
public static string Format(string formatWithNames, IDictionary<string,object> data) {
int pos = 0;
var args = new List<object>();
var fmt = Regex.Replace(
formatWithNames
, @"(?<={)[^}]+(?=})"
, new MatchEvaluator(m => {
var res = (pos++).ToString();
var tok = m.Groups[0].Value.Split(':');
args.Add(data[tok[0]]);
return tok.Length == 2 ? res+":"+tok[1] : res;
})
);
return string.Format(fmt, args.ToArray());
}
想法是用连续数字替换名称(参见sb.Append(pos++)
),构建一个对象参数数组(参见args.Add(data[tok[0]])
),并将结果传递给string.Format
以使用{{ 1}}的格式化功能。
现在,您可以将资源传递给此string
,以及键值对字典,并获取使用.NET内置格式化功能格式化的字符串:
Format
请注意,字符串文字前面没有var x = new Dictionary<string,object> {
{"brown", 1}
, {"jumps", 21}
, {"lazy", 42}
};
Console.WriteLine("{0}", Format("Quick {brown} fox {jumps:C} over the {lazy:P} dog", x));
,所以这里没有C#的内置插值。
打印
$
该方法基于idea by Scott Hanselman,但格式化方式不同。
答案 3 :(得分:5)
如果您不想使用字符串替换,则需要使用原始格式语法:
var pageTitle = "Shop the latest {0} Designer {1} {2} at www.abc.com";
var category1 = "womenswear";
var category2 = "dresses";
var category3 = "cocktail dresses";
var newTitle = string.Format(pageTitle, category1, category2, category3);
或在变量之后放置格式化字符串:
var category1 = "womenswear";
var category2 = "dresses";
var category3 = "cocktail dresses";
var newTitle = $"Shop the latest {0} Designer {0} {0} at www.abc.com";
字符串插值在编译时转换为string.Format
调用,因此无法在运行时使格式化字符串成为变量。
答案 4 :(得分:0)
请查看我的库,它解决了这个问题TinyTools如果你使用它并且喜欢它留下一个星。
var person = new Person
{
FirstName = "John",
LastName = "Smith"
};
var template = "Hello world, I'm {FirstName} {LastName}";
var result = template.Interpolate(person);
result.ShouldBe("Hello world, I'm John Smith");