Лучший способ заменить токены в большом текстовом шаблоне
У меня есть большой текстовый шаблон, который требует, чтобы разделы были заменены другим текстом. Токены выглядят примерно так: ## USERNAME ##. Мой первый инстинкт - это просто использовать String.Replace(), но есть ли более эффективный или более эффективный способ Replace()?
Ответы
Ответ 1
System.Text.RegularExpressions.Regex.Replace() - это то, что вы ищете - ЕСЛИ ваши жетоны достаточно странны, вам нужно найти регулярное выражение.
Некоторая душа сделала некоторые тесты производительности, а также между Regex.Replace(), String.Replace() и StringBuilder.Replace(), String.Replace() действительно вышел сверху.
Ответ 2
Единственная ситуация, в которой я должен был это сделать, - отправить шаблонное электронное письмо. В .NET это предоставляется из коробки класс MailDefinition. Таким образом, вы создаете шаблонное сообщение:
MailDefinition md = new MailDefinition();
md.BodyFileName = pathToTemplate;
md.From = "[email protected]";
ListDictionary replacements = new ListDictionary();
replacements.Add("<%To%>", someValue);
// continue adding replacements
MailMessage msg = md.CreateMailMessage("[email protected]", replacements, this);
После этого msg.Body будет создан путем замены значений в шаблоне. Я думаю, вы можете взглянуть на MailDefinition.CreateMailMessage() с Reflector:). Извините за то, что вы немного не по теме, но если это ваш сценарий, я думаю, что это самый простой способ.
Ответ 3
Ну, в зависимости от того, сколько переменных у вас есть в вашем шаблоне, сколько у вас шаблонов и т.д. это может быть работа для полного процессора шаблонов. Единственный, который я когда-либо использовал для .NET, - NVelocity, но я уверен, что там должно быть множество других, большинство из них связаны с некоторыми веб-фреймами или другими.
Ответ 4
string.Replace отлично. Я бы предпочел использовать Regex, но я *** для регулярных выражений.
Следует иметь в виду, насколько велики эти шаблоны. Если его реальный большой и память является проблемой, вы можете создать пользовательский токенизатор, который действует в потоке. Таким образом, вы храните только небольшую часть файла в памяти, пока вы манипулируете им.
Но для наивной реализации string.Replace должен быть в порядке.
Ответ 5
Если вы выполняете несколько заметок на больших строках, лучше использовать StringBuilder.Replace(), так как появятся обычные проблемы с производительностью со строками.
Ответ 6
Пришлось сделать что-то подобное недавно. Я сделал это:
- сделать метод, который принимает словарь (key = имя токена, value = текст, который нужно вставить)
- Получите все совпадения в вашем формате токена (##. +? ## в вашем случае, я думаю, не так хорошо в регулярных выражениях: P) с использованием Regex.Matches(ввод, регулярное выражение)
- foreach по результатам, используя словарь, чтобы найти значение вставки для вашего токена.
- возвращает результат.
Готово; -)
Если вы хотите проверить свои регулярные выражения, я могу предложить регулятор.
Ответ 7
Регулярные выражения будут самым быстрым решением для кода, но если у вас много разных токенов, он будет медленнее. Если производительность не является проблемой, используйте эту опцию.
Лучшим подходом было бы определить токен, например, ваш "##", который вы можете сканировать в тексте. Затем выберите, что заменить из хэш-таблицы текстом, который следует за токеном в качестве ключа.
Если это часть сборки script, то у nAnt есть отличная возможность для этого сделать Filter Chains. Код для этого является открытым исходным кодом, поэтому вы можете посмотреть, как это делается для быстрой реализации.
Ответ 8
FastReplacer реализует замену токена в O (n * log (n) + m) и использует 3x память исходной строки.
FastReplacer хорош для выполнения многих операций замены на большой строке, когда производительность важна.
Основная идея заключается в том, чтобы избежать изменения существующего текста или выделения новой памяти каждый раз при замене строки.
Мы разработали FastReplacer, чтобы помочь нам в проекте, где нам нужно было создать большой текст с большим количеством операций добавления и замены. Первая версия приложения заняла 20 секунд, чтобы сгенерировать текст с помощью StringBuilder. Вторая улучшенная версия, которая использовала класс String, заняла 10 секунд. Затем мы внедрили FastReplacer, а продолжительность - 0,1 секунды.
Ответ 9
Это идеальное использование регулярных выражений. Проверьте этот полезный веб-сайт, . Класс стандартных регулярных выражений, и эта очень полезная книга Освоение регулярных выражений.
Ответ 10
Если ваш шаблон большой, и у вас много токенов, вы, вероятно, не хотите его перемещать и заменять токен в шаблоне один за другим, так как это приведет к операции O (N * M), где N - размер шаблона, а M - количество заменяемых токенов.
Следующий метод принимает шаблон и словарь пар значений ключей, которые вы хотите заменить. Путем инициализации StringBuilder немного больше, чем размер шаблона, это должно привести к операции O (N) (то есть, ей не нужно увеличивать сам журнал N раз).
Наконец, вы можете переместить здание токенов в Singleton, поскольку его нужно только создать.
static string SimpleTemplate(string template, Dictionary<string, string> replacements)
{
// parse the message into an array of tokens
Regex regex = new Regex("(##[^#]+##)");
string[] tokens = regex.Split(template);
// the new message from the tokens
var sb = new StringBuilder((int)((double)template.Length * 1.1));
foreach (string token in tokens)
sb.Append(replacements.ContainsKey(token) ? replacements[token] : token);
return sb.ToString();
}