using System.Collections.Generic;
public static class Debug
public static void Log(string msg) => Console.WriteLine(msg);
public static void LogWarning(string msg) => Console.WriteLine(msg);
private static void ExtractParameters(string paramString, out string formatString, ISet<string> keys, List<string> keyOrder)
StringBuilder builder = new StringBuilder(paramString.Length);
while (left < paramString.Length && right < paramString.Length)
int nextLeft = paramString.IndexOf('{', right);
builder.Append(paramString.Substring(right, (left + 1) - right));
right = paramString.IndexOf('}', left + 1);
Debug.LogWarning("no closing brace in parameter string");
if (right - left - 1 > 0)
string key = paramString.Substring(left + 1, right - left - 1);
builder.Append(keyOrder.Count);
int commaIndex = key.IndexOf(',');
int colonIndex = key.IndexOf(':');
if (commaIndex > -1 || colonIndex > -1)
int divIndex = System.Math.Max(commaIndex, colonIndex);
string format = key.Substring(divIndex, key.Length - divIndex);
key = key.Substring(0, divIndex);
if (left == -1 && right == -1)
formatString = paramString;
builder.Append(paramString.Substring(left + 1, paramString.Length - (left + 1)));
builder.Append(paramString.Substring(right, paramString.Length - right));
formatString = builder.ToString();
private static string FillParameterFormat(string formatString, List<string> keyOrder, Dictionary<string, string> paramValues)
List<string> keyParams = new List<string>(keyOrder.Count);
foreach(string key in keyOrder)
string value = paramValues[key];
return string.Format(formatString, keyParams.ToArray());
public static void Main()
HashSet<string> keys = new HashSet<string>();
List<string> keyOrder = new List<string>();
ExtractParameters("{a:0.00} {b:0} {a:0.1}", out string format, keys, keyOrder);
var values = new Dictionary<string, object>()