我希望我的应用程序的最终用户编辑string.Format
中使用的格式字符串。我想这样做是为了让用户能够编辑模板。当用户输入太多标记时会出现问题。
这很好用:
var result = string.Format("test {0}, {1}, {2}", 1, 2, 3);
这也有效:
var result = string.Format("test {0}, {1}", 1, 2, 3);
但这引发了异常:
var result = string.Format("test {0}, {1}, {2}", 1, 2);
System.FormatException:'索引(从零开始)必须大于或 等于零且小于参数列表的大小。'
我知道我必须添加与标记一样多的参数,但最终用户不知道,或者他可以犯错误 - 添加额外的标记。
我的问题是:
我可以使用类似的方法来格式化字符串string.Format
,但无一例外。
我知道我可以使用try\catch
阻止并返回格式字符串,但我不想这样做。
我构建了一个非常简单的方法来替换字符串中的标记:
public static string SafeFormat(string format, params object[] args)
{
var result = format;
for (int i = 0; i < args.Length; i++)
{
result = result.Replace($"{{{i}}}", args[i].ToString());
}
return result;
}
但这不支持使用代替标记的数据格式化。
内部string.Format
正在使用比我的简单替换更复杂的AppendFormatHelper
(http://referencesource.microsoft.com/#mscorlib/system/text/stringbuilder.cs,2c3b4c2e7c43f5a4)。
理想情况下,string.Format("test {0}, {1}, {2}", 1, 2)
应返回test 1, 2, {2}
答案 0 :(得分:1)
一种解决方案是检查预期的值数,并将其他值附加到参数列表(null或占位符)。示例字符串扩展名:
public static class StringExtensions
{
public static string SafeFormat(this string value, params object[] args)
{
var pattern = @"{(.*?)}";
var matches = Regex.Matches(value, pattern);
var matchCount = matches.Count;
if (matchCount > args.Length)
{
var argsExtended = args.ToList();
for (int i = args.Length; i < matchCount; i++)
{
argsExtended.Add($"{{{i}}}"); //Can add null value to erase them
}
return string.Format(value, argsExtended.ToArray());
}
return string.Format(value, args);
}
}
如果需要,可以轻松将其更改为方法