Самый быстрый способ заменить строку в шаблоне

У меня есть строка шаблона

это мой {0} шаблон {1} строка

который я планирую поместить в пользовательские значения при использовании String.Format().

Строка на самом деле длиннее, поэтому для удобства чтения я использую:

это моя строка {goodName1} {goodName2}

И затем String.Replace каждый параметр со своим значением.

Как я могу получить максимальную производительность и удобство чтения?

Может быть, мне не нужно иметь этот шаблон в файле (как сейчас), но динамически строить его путем объединения в построитель строк и добавления параметров при необходимости? Хотя это менее читаемо.

Какие еще мои варианты?

Ответы

Ответ 2

Вы можете поместить параметры в словарь и использовать метод Regex.Replace для замены всех параметров в одной замене. Таким образом, метод хорошо масштабируется, если строка шаблона становится длинной или число параметров увеличивается.

Пример:

Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("goodName1", "asdf");
parameters.Add("goodName2", "qwerty");
string text = "this is my {goodName1} template {goodName2} string";
text = Regex.Replace(text, @"\{(.+?)\}", m => parameters[m.Groups[1].Value]);

Ответ 3

Как и все, это зависит. Если код будет называться миллионы раз каждый день, подумайте о производительности. Если это несколько раз в день, тогда идите на удобочитаемость.

Я сделал некоторый бенчмаркинг между использованием обычных (неизменяемых) строк и StringBuilder. До тех пор, пока вы не начнете делать огромную сумму за небольшие промежутки времени, вам не нужно слишком беспокоиться об этом.

Ответ 4

Мое спонтанное решение будет выглядеть так:

string data = "This is a {template1} that is {template2}.";

Dictionary<string, string> replacements = new Dictionary<string, string>(){
    {"{template1}", "car"},
    {"{template2}", "red"},
};

foreach (string key in replacements.Keys)
{
    data = data.Replace(key, replacements[key]);
}
Console.WriteLine(data); // outputs "This is a car that is red."

Я использовал такие замены шаблонов в нескольких проектах реального мира и никогда не обнаружил, что это проблема производительности. Поскольку он прост в использовании и понимании, я не вижу причин сильно его менять.

Ответ 5

ОСТОРОЖНО, чтобы увязнуть в этом типе мышления. Если этот код не работает сотни раз в минуту, а файл шаблона имеет размер несколько К, более важно сделать это. Не тратьте минутку на размышления о таких проблемах. В общем, если вы много работаете со строковыми манипуляциями, используйте конструктор строк. У него даже есть метод Replace. Но зачем беспокоиться. Когда вы закончите, и если вы обнаружите, что у вас проблема с производительностью, используйте PerfMon и устраните узкие места REAL в это время.

Ответ 6

Самый быстрый способ сделать это - с помощью StringBuilder, используя индивидуальные вызовы StringBuilder.Append(), например:

string result = new StringBuilder("this is my ")
                 .Append(UserVar1)
                 .Append(" template ")
                 .Append(UserVar2)
                 .Append(" string")
                 .ToString();

Я тщательно проверил код рамки, и это будет быстрее всего. Если вы хотите улучшить читаемость, вы можете сохранить отдельную строку, чтобы показать пользователя, и просто использовать это в фоновом режиме.

Ответ 7

То же самое, что выше, чем Фредрик, выше, но с linq.

    public static string FindandReplace(this string inputText, Dictionary<string, string> placeHolderValues)
    {
        if (!string.IsNullOrEmpty(inputText))
        {
            return placeHolderValues.Keys.Aggregate(inputText, (current, key) => current.Replace(key, placeHolderValues[key]));
        }
        else return inputText;
    }

Ответ 8

Если вам нужен хороший, быстрый, но простой механизм шаблонов, вы должны проверить StringTemplate. Для простых шаблонов, которые не требуют никакой логики или управления потоком в самом шаблоне, StringTemplate GREAT.

http://www.stringtemplate.org/download.html

Ответ 9

Просто изменил приведенный выше ответ на следующее:

    string data = "This is a {template1} that is {template2}.";

    Dictionary<string, string> replacements = new Dictionary<string, string>(){
        {"{template1}", "car"},
        {"{template2}", "red"},
    };

    data.Parse(replacements);

Метод расширения:

public static class Parser
{
    public static string Parse(this string template, Dictionary<string, string> replacements)
    {
        if (replacements.Count > 0)
        {
            template = replacements.Keys
                        .Aggregate(template, (current, key) => current.Replace(key, replacements[key]));
        }
        return template;
    }
}

Надеюсь, это поможет..:)