Один из способов сделать это - регулярные выражения.Для вашего примера вы могли бы сделать:
Regex regex = new Regex("^my (.*?) template (.*?) here$");
Match match = regex.Match("my 53 template 22 here");
string arg0 = match.Groups[1].Value; // = "53"
string arg1 = match.Groups[2].Value; // = "22"
Было бы нетрудно написать метод расширения, чтобы сделать именно то, что вы хотите, основываясь на этой технике.
Просто для удовольствия, вот мойпервая наивная попытка.Я не проверял это, но это должно быть близко.
public static object[] ExtractFormatParameters(this string sourceString, string formatString)
{
Regex placeHolderRegex = new Regex(@"\{(\d+)\}");
Regex formatRegex = new Regex(placeHolderRegex.Replace(formatString, m => "(<" + m.Groups[1].Value + ">.*?)");
Match match = formatRegex.Match(sourceString);
if (match.Success)
{
var output = new object[match.Groups.Count-1];
for (int i = 0; i < output.Length; i++)
output[i] = match.Groups[i+1].Value;
return output;
}
return new object[];
}
Это позволит вам сделать
object[] args = sourceString.ExtractFormatParameters("my {0} template {1} here");
Метод ОЧЕНЬ наивен и имеет много проблем, но в основном он найдет любые заполнители в выражении формата и найдет соответствующиетекст в исходной строке.Это даст вам значения, соответствующие заполнителям, перечисленным слева направо, без ссылки на порядковый номер или любой формат, указанный в заполнителе.Эта функциональность может быть добавлена.
Другая проблема состоит в том, что любые специальные символы регулярного выражения в строке формата вызовут падение метода.Необходимо выполнить дополнительную обработку formatRegex
, чтобы исключить любые специальные символы, которые являются частью formatString
.