如何使用命名标记而非数字占位符格式化外部输入的字符串?
基于命名占位符的动态字符串格式化实现方案
针对外部传入带{命名}占位符的模板、通过字典传值完成替换的需求,以下是两种可直接落地的实现方案:
方案1:原生正则实现(无第三方依赖)
核心逻辑是通过正则匹配所有命名占位符,再从字典中读取对应值完成替换,无需引入任何外部包,适配简单替换场景:
using System; using System.Collections.Generic; using System.Text.RegularExpressions; public static class NamedStringFormatter { // 匹配{xxx}格式的占位符,同时兼容{{xxx}}转义为普通文本的规则 private static readonly Regex _placeholderRegex = new Regex(@"(?<!\{)\{([a-zA-Z0-9_]+)\}(?!\})", RegexOptions.Compiled); public static string Format(string template, IReadOnlyDictionary<string, object> values) { return _placeholderRegex.Replace(template, match => { string key = match.Groups[1].Value; // 占位符不存在时可自定义处理逻辑:返回原占位符/抛异常/返回空字符串 return values.TryGetValue(key, out var value) ? value.ToString() : match.Value; }) // 处理转义的双大括号 .Replace("{{", "{") .Replace("}}", "}"); } }
使用示例:
// 外部输入的模板 string template = "用户{username}的ID是{id}, 注册时间是{registerDate}"; var values = new Dictionary<string, object> { {"username", "张三"}, {"id", 12345}, {"registerDate", new DateTime(2024,1,1)} }; string result = NamedStringFormatter.Format(template, values); // 输出:用户张三的ID是12345, 注册时间是2024/1/1 0:00:00
方案2:轻量模板引擎实现(适配复杂模板场景)
如果模板需要支持循环、条件判断等复杂逻辑,可以引入Scriban、*Mustache#*这类轻量模板引擎,原生支持命名占位符、运行时传值,不需要编译期绑定。
以Scriban为例,使用方式如下:
- 先安装NuGet包
Scriban - 代码示例:
using Scriban; string template = "用户{{username}}的ID是{{id}}{{if is_vip}},当前为VIP会员{{end}}"; var context = new TemplateContext(); context["username"] = "张三"; context["id"] = 12345; context["is_vip"] = true; var parsedTemplate = Template.Parse(template); string result = parsedTemplate.Render(context); // 输出:用户张三的ID是12345,当前为VIP会员
注意:如果模板来自用户任意输入,需要做好安全校验,限制模板可调用的权限范围,避免模板注入风险。
内容的提问来源于stack exchange,提问作者TheBoxyBear
相关产品推荐
相关产品推荐

