2009-05-27 14 views
3

Je construis actuellement ce petit moteur de gabarit. Il prend une chaîne contenant le modèle en paramètre, et un dictionnaire de "tags, valeurs" pour remplir le modèle.mise en œuvre du moteur de gabarit

Dans le moteur, je n'ai aucune idée des étiquettes qui seront dans le gabarit et celles qui ne le seront pas.

Je suis actuellement en train d'itérer (foreach) sur le dictionnaire, en analysant ma chaîne que j'ai mise dans un constructeur de chaînes, et en remplaçant les étiquettes dans le modèle par leur valeur correspondante.

Existe-t-il un moyen plus efficace/pratique de le faire? Je sais que le principal inconvénient est que le stringbuilder est analysé à chaque fois entièrement pour chaque balise, ce qui est assez mal ...

(je vérifie également, bien que non inclus dans l'échantillon, après le processus que mon modèle ne ne contient aucune balise plus Ils sont tous formated de la même manière. @@ tag @@)

//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(); 

Réponses:

@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"); 

Sortie: "texte dans un modèle de valeur2"

au lieu de: "Certains @@ foobar @@ texte dans un modèle de valeur2"

+0

(réponse au commentaire) –

+0

Fine ... use Dictionary au lieu de StringDictionary et il va lancer une erreur pour les clés manquées ... pas compliqué. –

Répondre

1

Que diriez-vous d'un Regex et MatchEvaluator? Comme si:

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

Complètement inutile dès que le motif va mal (comme un autre @ mal placé). Je m'en tiendrai à ma méthode de remplacement sauf si quelqu'un d'autre a une meilleure solution ... –

+0

Edit: En fait, inutile aussi si vous avez un tag comme ça @@ foo2 bar @@. Si dans le modèle vous avez quelque chose comme ça @@ foo bar @@, il est remplacé par un espace vide. Mauvaise solution pour la détection d'erreur –

+0

Pouvez-vous développer sur un point? "foo bar" devrait fonctionner correctement ... et je n'ai pas compris non plus votre "autre @ mal placé". Un exemple? –

0

Voici un exemple de code que vous pouvez utiliser comme point de départ:

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); 
    } 
} 
0

Vous pouvez modifier le format chaîne mono mise en œuvre en acceptant votre StringDictionary. Par exemple: