2009-05-27 6 views
3

В настоящее время я строю этот небольшой шаблон для шаблонов. Он принимает строку, содержащую шаблон в параметре, и словарь «теги, значения» для заполнения шаблона.template engine implementation

В двигателе я понятия не имею о тегах, которые будут в шаблоне, и те, которые не будут.

В настоящее время я выполняю итерацию (foreach) на dictionnary, разбор строки, которую я поместил в построитель строк, и заменив теги в шаблоне на их соответствующее значение.

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

(Я также проверяю, хотя и не включен в образец, после процесса, который мой шаблон делает не содержат какой-либо тег больше все они отформатированный таким же образом:. @@ @@ тега)

//Dictionary<string, string> tagsValueCorrespondence; 
//string template; 

StringBuilder outputBuilder = new StringBuilder(template); 
foreach (string tag in tagsValueCorrespondence.Keys) 
{ 
    outputBuilder.Replace(tag, tagsValueCorrespondence[tag]); 
} 

template = outputBuilder.ToString(); 

Отклики:

@Marc:

string template = "Some @@[email protected]@ text in a @@[email protected]@ template"; 
StringDictionary data = new StringDictionary(); 
data.Add("foo", "value1"); 
data.Add("bar", "value2"); 
data.Add("foo2bar", "value3"); 

Выход: "Некоторый текст в шаблоне значение2"

вместо: "Некоторые @@ Foobar @@ текст в шаблоне значение2"

+0

(ответил на комментарий) –

+0

Изобразительное ... использование Словарь вместо StringDictionary и это вызовет ошибку для пропущенных ключей ... не сложно. –

ответ

1

Как насчет Regex и MatchEvaluator? Как так:

string template = "Some @@[email protected]@ text in a @@[email protected]@ template"; 
StringDictionary data = new StringDictionary(); 
data.Add("foo", "random"); 
data.Add("bar", "regex"); 
string result = Regex.Replace(template, @"@@([^@]+)@@", delegate(Match match) 
{ 
    string key = match.Groups[1].Value; 
    return data[key]; 
}); 
+0

Полностью бесполезен, как только картина будет неправильной (как и другая @ неуместная). Я буду придерживаться метода замены, если у кого-то еще нет лучшего решения ... – 2009-06-01 08:43:44

+0

Редактировать: На самом деле, бесполезно, если у вас есть тег, подобный этому @@ foo2 bar @@. Если в шаблоне у вас есть что-то вроде @@ foo bar @@, оно заменяется пустым пространством. Плохое решение проблемы с обнаружением ошибок – 2009-06-01 08:48:00

+0

У вас есть расширение. «foo bar» должен по-прежнему работать нормально ... и я не понял ваш «другой @ неуместный» пункт. Любой пример? –

0

Вот пример кода, вы можете использовать в качестве отправной точки:

using System; 
using System.Collections.Generic; 
using System.Text.RegularExpressions; 

class Program { 
    static void Main() { 
     var template = " @@[email protected]@ @@[email protected]@ @@[email protected]@ @@Test [email protected]@"; 
     var replacement = new Dictionary<string, string> { 
       {"1", "Value 1"}, 
       {"2", "Value 2"}, 
       {"Test ZZ", "Value 3"}, 
      }; 
     var r = new Regex("@@(?<name>.+?)@@"); 
     var result = r.Replace(template, m => { 
      var key = m.Groups["name"].Value; 
      string val; 
      if (replacement.TryGetValue(key, out val)) 
       return val; 
      else 
       return m.Value; 
     }); 
     Console.WriteLine(result); 
    } 
}