Есть массив "шаблонных слов". Можно ли прочитав шаблон(pattern) с БД сделать автозамену "шаблонных слов" на нужные. Например
"Здраствуйте %client%. Ваш заказ %order% будет доставлен %date%".
Ну если есть массив Dictionary<string,string>
например, или если два массива - что заменять, и на что заменять. Т.е. встроеный шаблонизатор.
Или... хотя бы... делать это через Regex или есть более короткое рашение.
Странно, что никто в итоге не предложил вариант на регекспах, он, вроде, не сложен:
var template = "Здравствуйте, %client%! Ваш заказ %order% будет доставлен %date%.";
var pattern = "%.*?%";
var dict = new Dictionary<string, string>
{
["%client%"] = "Иван Иванович",
["%order%"] = "№007",
["%date%"] = "сегодня"
};
string evaluator(Match match) => dict.TryGetValue(match.Value, out var replacement) ? replacement : "n/a";
var result = Regex.Replace(template, pattern, evaluator);
Console.WriteLine(result);
Если не хотите держать в словаре все эти %
, можно искать не match.Value
, а match.Value.Trim('%')
Простой пример
var pattern = "%1% - %2% - %3%";
var dict = new Dictionary<string, string>() {{"%1%","odin"}, {"%2%","dwa"}, {"%3%","tri"}};
var res = dict.Aggregate(pattern, (acc, p)=>acc.Replace(p.Key, p.Value));
Console.WriteLine(res);
Вывод
odin - dwa - tri
Раз пошла такая пьянка, добавлю немного мракобесия
public string Format<T>(string source, T data)
{
var res = source;
foreach (var p in typeof(T).GetProperties())
res = res.Replace($"%{p.Name}%", p.GetValue(data)?.ToString());
return res;
}
var pattern = "%name% - %date% - %age%";
Console.WriteLine(Format(pattern, new {name = "vasya", date = DateTime.Now, age = 18}));
Вывод
vasya - 25-Jun-18 16:06:20 - 18
Самый простой способ - string.Format
:
var template = "Здравствуйте {0}. Ваш заказ {1} будет доставлен {2:dd.MM.yyyy}";
string.Format(template, "Вася", "фиговина", DateTime.Today);
При желании несложно сделать и выбор параметров по именам:
var template = "Здравствуйте {0:client}. Ваш заказ {0:order} будет доставлен {0:date:dd.MM.yyyy}";
string.Format(template, new CompositeFormattable(new
{
client = "Вася",
order = "фиговина",
date = DateTime.Today,
}));
// ...
class CompositeFormattable : IFormattable
{
private readonly object obj;
public CompositeFormattable(object obj)
{
this.obj = obj;
}
public string ToString(string format, IFormatProvider provider)
{
var index = format.IndexOf(':');
string propname;
if (index >= 0)
{
propname = format.Substring(0, index);
format = format.Substring(index + 1);
}
else
{
propname = format;
format = null;
}
var value = obj.GetType().GetProperty(propname).GetValue(obj);
if (value == null)
return null;
var formattableValue = value as IFormattable;
if (formattableValue != null)
return formattableValue.ToString(format, provider);
else
return value.ToString();
}
}
Вариант через регулярки также возможен (метод Regex.Replace).
У меня получилось так, хотя, может быть, не самым оптимальным образом
string textInput = "Здраствуйте %client%. Ваш заказ %order% будет доставлен %date%";
Dictionary<string, string> masks = new Dictionary<string, string>
{
{ "%client%", "Иванов" },
{ "%order%", "Заказ №123" },
{ "%date%", "2 апреля 23:05" },
};
var query = (from s in textInput.Split(' ')
from m in masks
select s.Replace(m.Key, m.Value) into r
where !r.StartsWith("%")
select r).Distinct();
string result = String.Join(" ", query);
Виртуальный выделенный сервер (VDS) становится отличным выбором
Я пишу TCP сервер-клиент приложение, часть которого которое реализует воспроизведение выбранного серверомmp3 файла на всех подключённых клиентах
В моей программе доступ к функции должно иметь только определенное количество потоковЕсть следующий код:
Хочу выводить нажатые клавиши пользователем, в том числе сочетанияПробовал разные Key Lisener/Hook (они работают по одному и тому же принципу), но везде...