C# 名为 String.Format,有可能吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1010123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
named String.Format, is it possible?
提问by
Instead of using {0} {1}
, etc. I want to use {title}
instead. Then fill that data in somehow (below I used a Dictionary
). This code is invalid and throws an exception. I wanted to know if i can do something similar to what i want. Using {0 .. N}
is not a problem. I was just curious.
而不是使用{0} {1}
等。我想使用{title}
。然后以某种方式填写该数据(下面我使用了 a Dictionary
)。此代码无效并引发异常。我想知道我是否可以做一些类似于我想做的事情。使用{0 .. N}
不是问题。我只是好奇而已。
Dictionary<string, string> d = new Dictionary<string, string>();
d["a"] = "he";
d["ba"] = "llo";
d["lol"] = "world";
string a = string.Format("{a}{ba}{lol}", d);
回答by micahtan
(your Dictionary + foreach + string.Replace) wrapped in a sub-routine or extension method?
(你的Dictionary + foreach + string.Replace)包裹在子例程还是扩展方法中?
Obviously unoptimized, but...
显然没有优化,但是......
回答by eulerfx
You can implement your own:
您可以实现自己的:
public static string StringFormat(string format, IDictionary<string, string> values)
{
foreach(var p in values)
format = format.Replace("{" + p.Key + "}", p.Value);
return format;
}
回答by LPCRoy
No, but this extension method will do it
不,但是这个扩展方法可以做到
static string FormatFromDictionary(this string formatString, Dictionary<string, string> valueDict)
{
int i = 0;
StringBuilder newFormatString = new StringBuilder(formatString);
Dictionary<string, int> keyToInt = new Dictionary<string,int>();
foreach (var tuple in valueDict)
{
newFormatString = newFormatString.Replace("{" + tuple.Key + "}", "{" + i.ToString() + "}");
keyToInt.Add(tuple.Key, i);
i++;
}
return String.Format(newFormatString.ToString(), valueDict.OrderBy(x => keyToInt[x.Key]).Select(x => x.Value).ToArray());
}
回答by jerryjvl
static public class StringFormat
{
static private char[] separator = new char[] { ':' };
static private Regex findParameters = new Regex(
"\{(?<param>.*?)\}",
RegexOptions.Compiled | RegexOptions.Singleline);
static string FormatNamed(
this string format,
Dictionary<string, object> args)
{
return findParameters.Replace(
format,
delegate(Match match)
{
string[] param = match.Groups["param"].Value.Split(separator, 2);
object value;
if (!args.TryGetValue(param[0], out value))
value = match.Value;
if ((param.Length == 2) && (param[1].Length != 0))
return string.Format(
CultureInfo.CurrentCulture,
"{0:" + param[1] + "}",
value);
else
return value.ToString();
});
}
}
A little more involved than the other extension method, but this should also allow non-string values and formatting patterns used on them, so in your original example:
比其他扩展方法稍微复杂一点,但这也应该允许在它们上使用非字符串值和格式模式,因此在您的原始示例中:
Dictionary<string, object> d = new Dictionary<string, object>();
d["a"] = DateTime.Now;
string a = string.FormatNamed("{a:yyyyMMdd-HHmmss}", d);
Will also work...
也会工作...
回答by Sean Carpenter
Phil Haack discussed several methods of doing this on his blog a while back: http://haacked.com/archive/2009/01/14/named-formats-redux.aspx. I've used the "Hanselformat" version on two projects with no complaints.
Phil Haack 不久前在他的博客上讨论了几种这样做的方法:http: //haacked.com/archive/2009/01/14/named-formats-redux.aspx。我在两个项目中使用了“Hanselformat”版本,没有任何抱怨。
回答by Pavlo Neiman
Check this one, it supports formating:
检查这个,它支持格式化:
public static string StringFormat(string format, IDictionary<string, object> values)
{
var matches = Regex.Matches(format, @"\{(.+?)\}");
List<string> words = (from Match matche in matches select matche.Groups[1].Value).ToList();
return words.Aggregate(
format,
(current, key) =>
{
int colonIndex = key.IndexOf(':');
return current.Replace(
"{" + key + "}",
colonIndex > 0
? string.Format("{0:" + key.Substring(colonIndex + 1) + "}", values[key.Substring(0, colonIndex)])
: values[key].ToString());
});
}
How to use:
如何使用:
string format = "{foo} is a {bar} is a {baz} is a {qux:#.#} is a really big {fizzle}";
var dictionary = new Dictionary<string, object>
{
{ "foo", 123 },
{ "bar", true },
{ "baz", "this is a test" },
{ "qux", 123.45 },
{ "fizzle", DateTime.Now }
};
StringFormat(format, dictionary)
回答by fabriciorissetto
It's possible now
现在有可能
With Interpolated Stringsof C# 6.0 you can do this:
使用C# 6.0 的内插字符串,您可以执行以下操作:
string name = "John";
string message = $"Hi {name}!";
//"Hi John!"
回答by danpop
Here is a nice solution that is very useful when formatting emails: http://www.c-sharpcorner.com/UploadFile/e4ff85/string-replacement-with-named-string-placeholders/
这是一个很好的解决方案,在格式化电子邮件时非常有用:http: //www.c-sharpcorner.com/UploadFile/e4ff85/string-replacement-with-named-string-placeholders/
Edited:
编辑:
public static class StringExtension
{
public static string Format( this string str, params Expression<Func<string,object>>[] args)
{
var parameters = args.ToDictionary( e=>string.Format("{{{0}}}",e.Parameters[0].Name), e=>e.Compile()(e.Parameters[0].Name));
var sb = new StringBuilder(str);
foreach(var kv in parameters)
{
sb.Replace( kv.Key, kv.Value != null ? kv.Value.ToString() : "");
}
return sb.ToString();
}
}
Example usage:
用法示例:
public string PopulateString(string emailBody)
{
User person = _db.GetCurrentUser();
string firstName = person.FirstName; // Peter
string lastName = person.LastName; // Pan
return StringExtension.Format(emailBody.Format(
firstname => firstName,
lastname => lastName
));
}
回答by Pavlo Neiman
Since C# 6 released you are able to use String Interpolation feature
自 C# 6 发布以来,您可以使用字符串插值功能
Code that solves your question:
解决您问题的代码:
string a = $"{d["a"]}{d["ba"]}{d["lol"]}";
回答by Dan Sorak
Why a Dictionary? It's unnecessary and overly complicated. A simple 2 dimensional array of name/value pairs would work just as well:
为什么是字典?这是不必要的,而且过于复杂。一个简单的名称/值对的二维数组也可以正常工作:
public static string Format(this string formatString, string[,] nameValuePairs)
{
if (nameValuePairs.GetLength(1) != 2)
{
throw new ArgumentException("Name value pairs array must be [N,2]", nameof(nameValuePairs));
}
StringBuilder newFormat = new StringBuilder(formatString);
int count = nameValuePairs.GetLength(0);
object[] values = new object[count];
for (var index = 0; index < count; index++)
{
newFormat = newFormat.Replace(string.Concat("{", nameValuePairs[index,0], "}"), string.Concat("{", index.ToString(), "}"));
values[index] = nameValuePairs[index,1];
}
return string.Format(newFormat.ToString(), values);
}
Call the above with:
调用上面的:
string format = "{foo} = {bar} (really, it's {bar})";
string formatted = format.Format(new[,] { { "foo", "Dictionary" }, { "bar", "unnecessary" } });
Results in: "Dictionary = unnecessary (really, it's unnecessary)"
结果是: "Dictionary = unnecessary (really, it's unnecessary)"