2016-01-29 3 views
0

J'ai un moteur de règles qui prend une chaîne comme nom d'une règle et la compare à une chaîne, un dictionnaire de prédicat. J'écris une règle qui va comparer deux dates et retourner vrai si elles correspondent, mais permettre une fenêtre d'un nombre configurable de secondes. Idéalement, je voudrais que ma paire de chaîne/valeur de clé principale à ressembler à quelque chose commeComment extraire une variable d'une chaîne J'ai besoin de la comparer à une autre chaîne préexistante C#

{"Allow <x> seconds", AllowXSeconds} 

Un utilisateur en appliquant la règle déciderait qu'ils aimeraient 10 secondes fenêtre de chaque côté de l'datetime d'origine afin qu'ils diraient "Autoriser 10 secondes" dans la configuration. Je veux que mon code soit capable de reconnaître que l'utilisateur veut appliquer la règle "Autoriser les secondes", puis retirer le "10" pour que je puisse l'utiliser comme une variable dans la logique de la règle. Je préfère ne pas utiliser regex, car la classe est déjà construite, et je ne sais pas si je serai autorisé à le refactoriser de cette façon. Je vais, cependant, si personne n'a d'idées intelligentes sur la façon de le faire. Merci d'avance, à vous tous les gars et les filles intelligents!

+0

-vous seulement besoin d'analyser la valeur ou valider également le format? – juharr

+0

Si je comprends ce que vous demandez, je pense que je dois aussi valider le format. Le moteur de règles doit savoir que la chaîne "Autoriser 10 secondes" est connectée à la méthode AllowXSeconds. – will

Répondre

0

Vous pouvez valider à l'aide string.StartsWith et string.EndsWith puis utilisez string.Substring pour obtenir la valeur désirée et int.TryParse pour tenter d'analyser la valeur et valider qu'il est un entier

string str = "Allow 10 seconds"; 
int result; 
if (str.StartsWith("Allow ") 
    && str.EndsWith(" seconds") 
    && int.TryParse(str.Substring(6, str.Length - 14), out result)) 
{ 
    Console.WriteLine(result); 
} 
else 
{ 
    Console.WriteLine("Invalid"); 
} 

également si vous le souhaitez, il y a des surcharges de StartsWith et EndsWith qui permettra également de faire une correspondance insensible à la casse.

0

Cela ressemble à un candidat idéal pour les expressions régulières.

Voici un programme LINQPad qui démontre:

void Main() 
{ 
    var lines = new[] 
    { 
     "Allow 10 seconds", 
     "Allow 5 seconds", 
     "Use 5mb" 
    }; 

    var rules = new Rule[] 
    { 
     new Rule(
      @"^Allow\s+(?<seconds>\d+)\s+seconds?$", 
      ma => AllowSeconds(int.Parse(ma.Groups["seconds"].Value))) 
    }; 

    foreach (var line in lines) 
    { 
     bool wasMatched = rules.Any(rule => rule.Visit(line)); 
     if (!wasMatched) 
      Console.WriteLine($"not matched: {line}"); 
    } 
} 

public void AllowSeconds(int seconds) 
{ 
    Console.WriteLine($"allow: {seconds} second(s)"); 
} 

public class Rule 
{ 
    public Rule(string pattern, Action<Match> action) 
    { 
     Pattern = pattern; 
     Action = action; 
    } 

    public string Pattern { get; } 
    public Action<Match> Action { get; } 

    public bool Visit(string line) 
    { 
     var match = Regex.Match(line, Pattern); 
     if (match.Success) 
      Action(match); 
     return match.Success; 
    } 
} 

Sortie:

allow: 10 second(s) 
allow: 5 second(s) 
not matched: Use 5mb