C# 如何为字符串格式提供自定义字符串占位符
我有一根绳子C# 如何为字符串格式提供自定义字符串占位符,c#,.net,string,string-formatting,C#,.net,String,String Formatting,我有一根绳子 string str ="Enter {0} patient name"; 我正在使用string.format格式化它 String.Format(str, "Hello"); 现在,如果我想从一些配置中检索患者,那么我需要将str更改为 “输入{0}{1}名称”。因此它将用第二个值替换{1}。问题是我想要的不是{1}而是其他格式,比如{pat}。但当我尝试使用时,它会抛出一个错误。我想要不同格式的原因是,有很多文件需要这样更改(可能包含{0}、{1}等)。因此,我需要一个可
string str ="Enter {0} patient name";
我正在使用string.format格式化它
String.Format(str, "Hello");
现在,如果我想从一些配置中检索患者,那么我需要将str更改为
“输入{0}{1}名称”
。因此它将用第二个值替换{1}。问题是我想要的不是{1}而是其他格式,比如{pat}
。但当我尝试使用时,它会抛出一个错误。我想要不同格式的原因是,有很多文件需要这样更改(可能包含{0}、{1}等)。因此,我需要一个可以在运行时替换的自定义占位符。Regex
带有MatchEvaluator
似乎是一个不错的选择:
static readonly Regex re = new Regex(@"\{([^\}]+)\}", RegexOptions.Compiled);
static void Main()
{
string input = "this {foo} is now {bar}.";
StringDictionary fields = new StringDictionary();
fields.Add("foo", "code");
fields.Add("bar", "working");
string output = re.Replace(input, delegate (Match match) {
return fields[match.Groups[1].Value];
});
Console.WriteLine(output); // "this code is now working."
}
你可能想在晚上结账。它允许您使用属性名称作为格式化标记,例如:
var user = new User()
{
Name = "Olle Wobbla",
Age = 25
};
Console.WriteLine("Your name is {Name} and your age is {Age}".FormatWith(user));
您还可以将其用于匿名类型
更新:还有一个类似的by,但它是作为一组扩展方法在对象
上实现的,而不是字符串
更新2012:您可以在
更新2014:还有和您最好对自定义字段使用替换,对其余字段使用格式,如:
string str = "Enter {0} {pat} name";
String.Format(str.Replace("{pat}", "Patient"), "Hello");
我看到了上面所有的答案,但是,我无法正确回答这个问题:) 以下代码不符合您的要求有什么特殊原因吗
string myFirstStr = GetMyFirstStrFromSomewhere();
string mySecondStr = GetMySecondStrFromSomewhere();
string result = "Enter " + myFirstStr + " " + mySecondStr + " name";
但是,您可以通过以下方式逃脱:
object[] myInts = new string[] { "8", "9" };
string bar = string.Format("{0} {1}", myInts);
这是我在这里找到的另一个版本: 对此的任何解决方案都将涉及反射,这并不理想,但下面是他的代码,其中解决了一些其他主要性能问题。(无错误检查。如果愿意,请添加它。): 1) 使用直接运行时反射,无DataBinder开销 2) 不使用正则表达式,使用单次传递解析和状态 3) 不会将字符串转换为中间字符串,然后再将其转换为最终格式 4) 使用单个StringBuilder进行分配和连接,而不是在整个位置上更新字符串并将其连接到新字符串中 5) 删除为n个替换操作调用委托的堆栈开销 6) 通常是一个单通道,它将以相对线性的方式进行缩放(每个道具查找和嵌套道具查找仍需要一些成本,仅此而已。)
公共静态字符串格式(此字符串格式,对象源)
{
StringBuilder sbResult=新的StringBuilder(format.Length);
StringBuilder sbCurrentTerm=新的StringBuilder();
char[]formatChars=format.tocharray();
bool inTerm=假;
对象currentPropValue=源;
for(int i=0;i
您还可以使用Marc Gravell中的示例并扩展String类对象:
public static class StringExtension
{
static readonly Regex re = new Regex(@"\{([^\}]+)\}", RegexOptions.Compiled);
public static string FormatPlaceholder(this string str, Dictionary<string, string> fields)
{
if (fields == null)
return str;
return re.Replace(str, delegate(Match match)
{
return fields[match.Groups[1].Value];
});
}
}
公共静态类StringExtension
{
静态只读正则表达式re=newregex(@“\{([^\}]+)\}”,RegexOptions.Compiled);
公共静态字符串格式占位符(此字符串str,字典字段)
{
如果(字段==null)
返回str;
返回重新替换(str,委托(匹配)
{
返回字段[match.Groups[1].Value];
});
}
}
用法示例:
String str = "I bought a {color} car";
Dictionary<string, string> fields = new Dictionary<string, string>();
fields.Add("color", "blue");
str.FormatPlaceholder(fields));
String str=“我买了一辆{color}车”;
字典字段=新字典();
字段。添加(“颜色”、“蓝色”);
str.FormatPlaceholder(字段));
我想要更像Python字符串格式的东西,所以我写了以下内容:
像这样使用它:
Dim template = New FormatFromDictionary("{cat} vs {dog}")
Dim d = New Dictionary(Of String, Object) From {
{"cat", "Felix"}, {"dog", "Rex"}}
Console.WriteLine(template.Replace(d)) ' Felix vs Rex
+那很有趣,我以前没见过。看起来它可以很好地处理匿名类型。在链接文章中,一些评论者关注性能。请确保在使用之前查看性能是否可以接受。必须使用Scott的版本,因为FormatWith似乎依赖于System.Web。它可以工作,但问题是OP不喜欢
{0}
数字占位符,需要更具描述性的占位符。通常是因为字符串来自其他地方,如翻译资源或某种用户可编辑模板。
String str = "I bought a {color} car";
Dictionary<string, string> fields = new Dictionary<string, string>();
fields.Add("color", "blue");
str.FormatPlaceholder(fields));
Dim template = New FormatFromDictionary("{cat} vs {dog}")
Dim d = New Dictionary(Of String, Object) From {
{"cat", "Felix"}, {"dog", "Rex"}}
Console.WriteLine(template.Replace(d)) ' Felix vs Rex