我正在尝试使用特定上下文/范围内的可用变量来动态格式化某些字符串。
此字符串包含{{parameter1}}
,{{parameter2}}
之类的内容,这些变量将存在于我将尝试重新格式化该字符串的范围内。变量名称应该匹配。
我一直在寻找诸如动态字符串插值方法之类的方法,或者如何使用FormattableStringFactory,但是我发现没有什么能真正满足我的需求。
var parameter1 = DateTime.Now.ToString();
var parameter2 = "Hello world!";
var retrievedString = "{{parameter2}} Today we're {{parameter1}}";
var result = MagicMethod(retrievedString, parameter1, parameter2);
// or, var result = MagicMethod(retrievedString, new { parameter1, parameter2 });
是否存在现有的解决方案,或者(MagicMethod
中的这些部分应该用作为参数指定的匿名对象的匹配成员(使用反射或类似方法)替换retrievedString
中的这些部分?>
编辑:
最后,我创建了一个扩展方法来处理此问题:
internal static string SpecialFormat(this string input, object parameters) {
var type = parameters.GetType();
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex( "\\{(.*?)\\}" );
var sb = new System.Text.StringBuilder();
var pos = 0;
foreach (System.Text.RegularExpressions.Match toReplace in regex.Matches( input )) {
var capture = toReplace.Groups[ 0 ];
var paramName = toReplace.Groups[ toReplace.Groups.Count - 1 ].Value;
var property = type.GetProperty( paramName );
if (property == null) continue;
sb.Append( input.Substring( pos, capture.Index - pos) );
sb.Append( property.GetValue( parameters, null ) );
pos = capture.Index + capture.Length;
}
if (input.Length > pos + 1) sb.Append( input.Substring( pos ) );
return sb.ToString();
}
我这样称呼它:
var parameter1 = DateTime.Now.ToString();
var parameter2 = "Hello world!";
var retrievedString = "{parameter2} Today we're {parameter1}";
var result = retrievedString.SpecialFormat( new { parameter1, parameter2 } );
现在,我不再使用双括号。
答案 0 :(得分:4)
您可以结合使用反射和匿名类型来做到这一点:
public string StringFormat(string input, object parameters)
{
var properties = parameters.GetType().GetProperties();
var result = input;
foreach (var property in properties)
{
result = result.Replace(
$"{{{{{property.Name}}}}}", //This is assuming your param names are in format "{{abc}}"
property.GetValue(parameters).ToString());
}
return result;
}
并这样称呼它:
var result = StringFormat(retrievedString, new { parameter1, parameter2 });
答案 1 :(得分:2)
虽然不了解您遇到的困难,但我还是打赌
Replace( string oldValue, string newValue )
您可以用所需的数据替换“标签”。
var parameter1 = DateTime.Now.ToString();
var parameter2 = "Hello world!";
var retrievedString = "{{parameter2}} Today we're {{parameter1}}";
var result = retrievedString.Replace("{{parameter2}}", parameter2).Replace({{parameter1}}, parameter1);
编辑
作者提到他正在寻找可以接受参数并迭代列表的东西。可以通过类似
的方法来完成public static void Main(string[] args)
{
//your "unmodified" srting
string text = "{{parameter2}} Today we're {{parameter1}}";
//key = tag(explicitly) value = new string
Dictionary<string, string> tagToStringDict = new Dictionary<string,string>();
//add tags and it's respective replacement
tagToStringDict.Add("{{parameter1}}", "Foo");
tagToStringDict.Add("{{parameter2}}", "Bar");
//this returns your "modified string"
changeTagWithText(text, tagToStringDict);
}
public static string changeTagWithText(string text, Dictionary<string, string> dict)
{
foreach (KeyValuePair<string, string> entry in dict)
{
//key is the tag ; value is the replacement
text = text.Replace(entry.Key, entry.Value);
}
return text;
}
函数changeTagWithText
将返回:
“今天我们是酒吧吧”
使用此方法,您可以将所有标签添加到字典中,并且它将自动替换所有标签。
答案 2 :(得分:-1)
如果您知道参数的顺序,则可以使用string.Format()
方法(msdn)。然后,您的代码将如下所示:
var parameter1 = DateTime.Now.ToString();
var parameter2 = "Hello world!";
var retrievedString = " Today we're @Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "UserID", nullable = true)
public int getUserId() {
return this.userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
";
var result = string.Format(retrievedString, parameter2, parameter1);