2010-11-01 5 views
3

Conversion d'un ancien programme en site ASP.NET C#.Chaîne rapide Remplacer par un caractère générique

J'ai une table pleine de fonctions et une table pleine de variables avec leurs valeurs correspondantes. J'ai écrit une fonction pour évaluer les réponses, mais besoin de formater les formules pour passer la variable dans

Par exemple:.

V(totalValue) * V(CoFriction(s)) ==> V("totalValue") * V("CoFriction(s)") 

Comment puis-je remplacer le V(<variable>)-V("<variable>"). Les parenthèses imbriquées sont possibles!

J'ai essayé la regexp comme - V\([^\(\)]+\) seulement pour échouer sur le parent imbriqué.

+1

Eh bien, si les parenthèses imbriquées sont permises/possibles, comment détermineriez-vous quand la valeur est un littéral de chaîne et quand ce n'est pas le cas? Qu'est-ce que cela signifierait quand une fonction qui doit être traitée comme un littéral de chaîne a une autre fonction en tant que paramètre qui doit également être traitée comme une chaîne littérale? Il me semble que vous avez besoin d'écrire un analyseur de descente récursif simple qui, dès qu'il trouve un nom de fonction dont il a connaissance, commence la correspondance des parenthèses jusqu'à ce que le crochet de fermeture soit trouvé et entoure tout le lot de virgules inversées. Sinon, vous devrez évaluer les fonctions nommées au moment de l'exécution. – Kell

Répondre

2

Vous pouvez achive en .net l'aide d'un groupe d'équilibrage:

string s = "V(totalValue) * V(CoFriction(s)) * V(a(()b)c()d((())))"; 

string vPattern = 
@"V\(
(  #capturing group, for $1 to work 
    (?: 
     (?<open>\()| #push to stack OR 
     (?<-open>\))| #pop from stack OR 
     [^()]   #match anything else 
    )+? 
) 
(?(open)(?!)) #assert there are not extra (
\)"; 

s = Regex.Replace(s, vPattern, "V(\"$1\")", RegexOptions.IgnorePatternWhitespace); 

Le regex fonctionne exactement les scénarios affichés - il échouera lamentablement si l'entrée est pas valide, vous assumez ce est (en particulier, lorsque vous avez des parenthèses de fermeture supplémentaires).

+0

Wow, j'ai appris quelque chose de nouveau :) Mais oui, je ne suis pas sûr de pouvoir l'utiliser! – Kell

+0

@Kell - Merci. Cette notation spécifique à .Net et au-delà de la récréation n'a été utilisée que de manière limitée, mais elle est bien adaptée à ce cas - elle permet de capturer des jetons équilibrés, mais pas de capturer chaque paire de parenthèses. Bien sûr, il n'est pas difficile de compter manuellement les parenthèses, ce qui est une solution valable. – Kobi

1

J'ai construit des bibliothèques comme celle-ci dans le passé. La fonctionnalité Regex que vous voulez est appelée "groupes d'équilibrage". Il y a une bonne writeup à http://blog.stevenlevithan.com/archives/balancing-groups Je pense que vous voulez quelque chose comme ceci:

V\((?>[^()]+|\((?<Depth>)|\) (?<-Depth>))*(?(Depth)(?!))\) 

Si je me souviens bien cela essentiellement ajouter un PAREN sur la pile « de profondeur » quand il voit un open-paren, retirez-le de la " Profondeur "pile quand il voit un parent proche (s'il n'y en a aucun sur la pile, il échoue), puis échoue d'un parent ouvert n'est pas fermé.

Questions connexes