2010-03-07 6 views
4

Je dispose d'un modèle de texte avec des placehoders que j'analyse afin de remplacer les espaces réservés par des valeurs réelles.Analyse textuelle, texte conditionnel

texte Modèle:

Name:%name% 
Age:%age% 

J'utilise StringBuilder.Replace() pour remplacer les espaces réservés

sb.Replace("%name%", Person.Name); 

Maintenant, je veux faire algorithme plus avancé. Certaines lignes de code sont conditionnelles. Ils doivent être soit complètement enlevés de gardé.

Text Template

Name:%Name% 
Age:%age% 
Employer:%employer% 

L'employeur de ligne ne doit apparaître que lorsque la personne est employée (contrôlée par Person.IsEmployed booléenne variable).

MISE À JOUR: Je pourrais utiliser des balises d'ouverture/fermeture. Comment trouver du texte entre la chaîne A et B? Puis-je utiliser Regex? Comment?

Répondre

1

Votre régime actuel templating est pas assez robuste - vous devez ajouter des espaces réservés plus spéciaux, comme celui-ci par exemple:

Name:%Name% 
Age:%age% 
[if IsEmployed] 
Employer:%employer% 
[/if] 

Vous pouvez analyser sur [si *] blocs en utilisant une expression régulière (non testé):

Match[] ifblocks = Regex.Match(input, "\\[if ([a-zA-Z0-9]+)\\]([^\\[]*)\\[/if\\]"); 
foreach(Match m in ifblocks) { 
    string originalBlockText = m.Groups[0]; 
    string propertyToCheck = m.Groups[1]; 
    string templateString = m.Groups[2]; 

    // check the property that corresponds to the keyword, i.e. "IsEmployed" 

    // if it's true, do the normal replacement on the templateString 
    // and then replace the originalBlockText with the "filled" templateString 

    // else, just don't write anything out 
} 

vraiment, cependant, cette mise en œuvre est pleine de trous ... Vous pouvez être mieux avec un cadre comme une autre réponse templating suggéré.

4

Peut-être que vous pourriez inclure l'étiquette "Employeur:" dans le texte de remplacement au lieu du modèle:

Modèle:

Name:%Name% 
Age:%age% 
%employer% 

remplacement

sb.Replace("%employer%", 
    string.IsNullOrEmpty(Person.Employer) ? "" : "Employer: " + Person.Employer) 
+0

Comment puis-je définir que l'étiquette ne concerne qu'une zone de texte spécifique? Je pense que je dois introduire des balises d'ouverture/fermeture. –

1

Une option serait de faire Remplacez toutes les variables vides par un remplacement RegEx sur le chemin de la porte. Quelque chose comme ceci:

Response.Write(RegEx.Replace(sb.ToString(), "\r\n[^:]+:r\n", "\r\n")); 
2

Une autre alternative pourrait être d'utiliser un moteur de modèle tels que Spark ou NVelocity.

Voir un exemple rapide pour Spark here

Un moteur de modèle à part entière devrait vous donner le plus de contrôle sur la sortie formatée. Par exemple conditionnels et sections répétées.