Fast String Replace with Wildcard
Converting an old program into an ASP.NET c# site.
I have a table full of functions and a table full of variables with their corresponding values. I've written a function to evaluate the answers but need to format the formulas in order to pass the variable in.
For example:
V(totalValue) * V(CoFriction(s)) ==> V("totalValue") * V("CoFriction(s)")
How can I replace the V(<variable>)
to V开发者_运维问答("<variable>")
. Nested parenthesis are possible!
I've tried regexp like - V\([^\(\)]+\)
only to fail on the nested paren.
You can achive it in .net using a balancing group:
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);
The regex works exactly for the posted scenarios - it will fail miserably if the input isn't valid, so you assume it is (specifically, when you have extra closing parentheses).
I've built libraries like this in the past. The Regex feature you want is called "balancing groups". There's a good writeup at http://blog.stevenlevithan.com/archives/balancing-groups I think you want something like this:
V\((?>[^()]+|\( (?<Depth>)|\) (?<-Depth>))*(?(Depth)(?!))\)
If I remember correctly this will essentially add a paren onto the "Depth" stack when it sees an open-paren, remove it from the "Depth" stack when it sees a close paren (if there is none on the stack it fails), and then fails of an open paren isn't closed.
精彩评论