是否有任何函数可以从格式字符串中查询预期的输入和格式 - 即一个用作String.Format
函数的第一个参数?
e.g。给出:
"On {0:yyyyy-MM-dd} do {1} and earn {2:C2}"
我希望得到类似的内容:
{"yyyyy-MM-dd", null, "C2"}
我认为正则表达式是一种可能性,但是有什么预先设定与String.Format
挂钩的逻辑吗?
答案 0 :(得分:1)
String.Format本身并不解析格式字符串。它最终调用内部StringBuilder.AppendFormatHelper方法,该方法仅将格式字符串视为分隔字符串。它并没有尝试解析它们。格式直接传递给每个参数类型的格式化方法。对于运行时和应用程序,字符串格式化性能至关重要。
您可以使用正则表达式来解析格式字符串。您需要处理转义大括号({{,{})和对齐字符串。
正则表达式{(?<index>\d+)(,(?<algn>-?\d+?))?(:(?<fmt>.*?))?}
将索引,对齐和格式段提取为命名组。它没有明确地处理转义的大括号*。它将避免{{ {}
但不会{{2,20:N{}
:
var regex=new System.Text.RegularExpressions.Regex(@"{(?<index>\d+)(,(?<algn>-?\d+?))?(:(?<fmt>.*?))?}");
var matches=regex.Matches("asdf{0:d2} {1:yyyy-MM-dd} {2,-20:N2}");
foreach(Match match in matches)
{
Console.WriteLine("{0,-5} {1,-15} {2,-15}",
match.Groups["index"].Value,
match.Groups["algn"].Value,
match.Groups["fmt"].Value);
}
这将返回:
0 d2
1 yyyy-MM-dd
2 -20 N2
(?<name>...)
语法捕获模式并将其公开为命名组。 (?<index>\d+)
捕获一系列数字并将其公开为组index
。
?
中的.*?
指定非贪婪匹配。通常,正则表达式是贪婪的 - 它将捕获尽可能多的字符匹配模式。通过使用.*?
,正则表达式将在下一个模式开始之前捕获尽可能少的字符。这就是可选的algn
组在:
停止的原因。
答案 1 :(得分:0)
机会不是标准的手段。使用Regex,很简单:
var args = new List<string>();
var str = "On {0:yyyyy-MM-dd} do {1} and earn {2:C2}";
MatchCollection matches = Regex.Matches(str, @"\{\d+[^\{\}]*\}");
foreach (Match match in matches)
{
string obj = null;
var split = match.ToString().Split(':');
if (split.Length == 2) obj = split.Last().Trim(' ', '}', '{');
args.Add(obj);
}
// Result: args = {"yyyyy-MM-dd", null, "C2"}