Regex to extract function-name, & it's parameters - c#

I am building an application where the user can specify an expression for some fields. The expression shall contain functions too. I need to evaluate these expressions and display final value in report.
I had an expression to extract function-name & it's paramters. Previously, the function parameters were decimal values. But now, the parameters can also be expression.
For ex,
Round( 1 * (1+ 1 /100) % (2 -1), 0)
Function-name : Round
Parameter1 : 1 * (1+ 1 /100) % (2 -1)
Parameter2 : 0
Previous Regex:
string pattern2 = #"([a-zA-Z]{1,})[[:blank:]]{0,}\(([^\(\)]{0,})\)";
This regex does not help me anymore to find expression-parameters.
Can someone help me with the right regex to extract function-name & parameters? I am implement all or most of the functions supported by Math class.
The program is built in c#
Thanks in advance for the help.

"^\s*(\w+)\s*\((.*)\)"
group(1) is function name
split group(2) with "," you get para list.
updated
since I don't have Windows system (.Net either), I test it with python. nested function is not a problem. if we add "^\s*" at the beginning of the expression:
import re
s="Round(floor(1300 + 0.234 - 1.765), 1)"
m=re.match("^\s*(\w+)\s*\((.*)\)",s)
m.group(1)
Output: 'Round'
m.group(2)
Output: 'floor(1300 + 0.234 - 1.765), 1'
you can split if you like:
m.group(2).split(',')[0]
Out: 'floor(1300 + 0.234 - 1.765)'
m.group(2).split(',')[1]
Out: ' 1'
well, if your function nesting is like f(a(b,c(x,y)),foo, m(j,k(n,o(i,u))) ), my code won't work.

You could try writing a parser, instead of using regular expressions.
The Irony library is (in my opinion) extremely easy to use, and in the examples there's something very similar to what you are trying to do.

From the post Regex for matching Functions and Capturing their Arguments, you can extract your function using Kent regex and use this code to extract parameters form the last group :
string extractArgsRegex = #"(?:[^,()]+((?:\((?>[^()]+|\((?<open>)|\)(?<-open>))*\)))*)+";
var ArgsList = Regex.Matches(m.Groups[m.Groups.Count - 1].Value, extractArgsRegex);

Related

Using $ sign vs # sign to avoid string interruption [duplicate]

This question already has answers here:
What does $ mean before a string?
(11 answers)
Closed 6 years ago.
I have been looking over some C# exercises in a book and I ran across an example that stumped me. Straight from the book, the output line shows as:
Console.WriteLine($"\n\tYour result is {result}.");
The code works and the double result shows as expected. However, not understanding why the $ is there at the front of the string, I decided to remove it, and now the code outputs the name of the array {result} instead of the contents. The book doesn't explain why the $ is there, unfortunately.
I have been scouring the VB 2015 help and Google, regarding string formatting and Console.WriteLine overload methods. I am not seeing anything that explains why it is what it is. Any advice would be appreciated.
It's the new feature in C# 6 called Interpolated Strings.
The easiest way to understand it is: an interpolated string expression creates a string by replacing the contained expressions with the ToString representations of the expressions' results.
For more details about this, please take a look at MSDN.
Now, think a little bit more about it. Why this feature is great?
For example, you have class Point:
public class Point
{
public int X { get; set; }
public int Y { get; set; }
}
Create 2 instances:
var p1 = new Point { X = 5, Y = 10 };
var p2 = new Point { X = 7, Y = 3 };
Now, you want to output it to the screen. The 2 ways that you usually use:
Console.WriteLine("The area of interest is bounded by (" + p1.X + "," + p1.Y + ") and (" + p2.X + "," + p2.Y + ")");
As you can see, concatenating string like this makes the code hard to read and error-prone. You may use string.Format() to make it nicer:
Console.WriteLine(string.Format("The area of interest is bounded by({0},{1}) and ({2},{3})", p1.X, p1.Y, p2.X, p2.Y));
This creates a new problem:
You have to maintain the number of arguments and index yourself. If the number of arguments and index are not the same, it will generate a runtime error.
For those reasons, we should use new feature:
Console.WriteLine($"The area of interest is bounded by ({p1.X},{p1.Y}) and ({p2.X},{p2.Y})");
The compiler now maintains the placeholders for you so you don’t have to worry about indexing the right argument because you simply place it right there in the string.
For the full post, please read this blog.
String Interpolation
is a concept that languages like Perl have had for quite a while, and
now we’ll get this ability in C# as well. In String Interpolation, we
simply prefix the string with a $ (much like we use the # for verbatim
strings). Then, we simply surround the expressions we want to
interpolate with curly braces (i.e. { and }):
It looks a lot like the String.Format() placeholders, but instead of an index, it is the expression itself inside the curly braces. In fact, it shouldn’t be a surprise that it looks like String.Format() because that’s really all it is – syntactical sugar that the compiler treats like String.Format() behind the scenes.
A great part is, the compiler now maintains the placeholders for you so you don’t have to worry about indexing the right argument because you simply place it right there in the string.
C# string interpolation is a method of concatenating,formatting and manipulating strings. This feature was introduced in C# 6.0. Using string interpolation, we can use objects and expressions as a part of the string interpolation operation.
Syntax of string interpolation starts with a ‘$’ symbol and expressions are defined within a bracket {} using the following syntax.
{<interpolatedExpression>[,<alignment>][:<formatString>]}
Where:
interpolatedExpression - The expression that produces a result to be formatted
alignment - The constant expression whose value defines the minimum number of characters in the string representation of the
result of the interpolated expression. If positive, the string
representation is right-aligned; if negative, it's left-aligned.
formatString - A format string that is supported by the type of the expression result.
The following code example concatenates a string where an object, author as a part of the string interpolation.
string author = "Mohit";
string hello = $"Hello {author} !";
Console.WriteLine(hello); // Hello Mohit !
Read more on C#/.NET Little Wonders: String Interpolation in C# 6

C# Regular Expressions Replace

I'm trying to rewrite some text that contains URLs such as:
"/route/id"
"/base/route/id"
"/route2/id"
"/base/route2/id"
of which there will be many in the text. The quotes are part of the text being matched.
All these URLs need to be of the format "/base/..." so I need to rewrite "/ to "/base/ unless the "/base is already there. Which is the bit I'm struggling with. I can replace the "/ but not when it's already followed by base.
No need for Regex:
var listOfThingsAllWithBase = listOfThings.Select(a => a.StartsWith("\"/base") ? a : "\"/base" + a.Substring(1, a.Length - 2));
My regex is a little rusty, but if I remember correctly, this should find all entries not starting with /base
^(?!/base)

Regex in C# - remove quotes and escaped quotes from a value after another value

I am using HighCharts and am generating script from C# and there's an unfortunate thing where they use inline functions for formatters and events. Unfortunately, I can't output JSON like that from any serializer I know of. In other words, they want something like this:
"labels":{"formatter": function() { return Highcharts.numberFormat(this.value, 0); }}
And with my serializers available to me, I can only get here:
"labels":{"formatter":"function() { return Highcharts.numberFormat(this.value, 0); }"}
These are used for click events as well as formatters, and I absolutely need them.
So I'm thinking regex, but it's been years and years and also I was never a regex wizard.
What kind of Regex replace can I use on the final serialized string to replace any quoted value that starts with function() with the unquoted version of itself? Also, the function itself may have " in it, in which case the quoted string might have \" in it, which would need to also be replaced back down to ".
I'm assuming I can use a variant of the first answer here:
Finding quoted strings with escaped quotes in C# using a regular expression
but I can't seem to make it happen. Please help me for the love of god.
I've put more sweat into this, and I've come up with
serialized = Regex.Replace(serialized, #"""function\(\)[^""\\]*(?:\\.[^""\\]*)*""", "function()$1");
However, my end result is always:
formatter:function()$1
This tells me I'm matching the proper stuff, but my capture isn't working right. Now I feel like I'm probably being an idiot with some C# specific regex situation.
Update: Yes, I was being an idiot. I didn't have a capture around what I really wanted.
`enter code here` serialized = Regex.Replace(serialized, #"""function\(\)([^""\\]*(?:\\.[^""\\]*)*)""", "function()$1");
that gets my match, but in a case like this:
"formatter":"function() { alert(\"hi!\"); return Highcharts.numberFormat(this.value, 0); }"
it returns:
"formatter":function() { alert(\"hi!\"); return Highcharts.numberFormat(this.value, 0); }
and I need to get those nasty backslashes out of there. Now I think I'm truly stuck.
Regexp for match
"function\(\) (?<code>.*)"
Replace expression
function() ${code}
Try this : http://regexr.com?30jpf
What it does :
Finds double quotes JUST before a function declaration and immediately after it.
Regex :
(")(?=function()).+(?<=\})(")
Replace groups 1 & 3 with nothing :
3 capturing groups:
group 1: (")
group 2: ()
group 3: (")
string serialized = JsonSerializer.Serialize(chartDefinition);
serialized = Regex.Replace(serialized, #"""function\(\)([^""\\]*(?:\\.[^""\\]*)*)""", "function()$1").Replace("\\\"", "\"");

C-sharp math issue with square root

How do i Evaluate the following expression from a string to a answer as an integer?
Expression:
√(7+74) + √(30+6)
Do i have to evaluate each one of the parameters like Sqroot(7+74) and Sqroot(30+6) or is it possible to evaluate the whole expression. Any ideas?
If this string is user-supplied (or anyway available only at runtime) what you need is a mathematical expressions parser (maybe replacing the √ character in the text with sqrt or whatever the parser likes before feeding the string to it). There are many free ones available on the net, personally I used info.lundin.math several times without any problem.
Quick example for your problem:
info.lundin.Math.ExpressionParser parser = new info.lundin.Math.ExpressionParser();
double result = parser.Parse("sqrt(7+74)+sqrt(30+6)", null);
(on the site you can find more complex examples with e.g. parameters that can be specified programmatically)
You can use NCalc for this purpose
NCalc.Expression expr = new NCalc.Expression("Sqrt(7+74) + Sqrt(30+6)");
object result = expr.Evaluate();

How to drop some characters with Regex in vs?

I have a sql table and I have a column which includes data such as: B757-34-11-00-I-1, A300-223100-0503-1 etc.
A300-223100-0503-1 -> 223100-0503-1
B757-34-11-00-I-1 -> 34-11-00-I-1
How can i do that with regex? I need two kinds of solutions: sql and C#. how can I do that with sql query in SQL and C#
i need drop charater as far as "-" may be dropping more than 5 characters or less than? i need also drop "-"
A regular expression is overkill for simple string manipulation like this.
C#:
value.Substring(value.indexOf('-') + 1)
SQL:
substring(field, charindex('-', field) + 1, 1000)
(The last parameter could be calculated as len(field) - charindex('-', field) - 1, but you can just use a value that you know is larger than the max length.)
Is it always just dropping the first 5 characters? If so, you don't need to use a regex at all.
C#:
value = value.Substring(5);
T-SQL:
SELECT SUBSTRING(field, 5, LEN(field) - 5)
In SQL:
SUBSTRING(col, PATINDEX('%-%', col) + 1)
in C#:
val.Substring(val.IndexOf('-') + 1)
This requirement is so simple, there is no need for regexes (and SQL Server does not natively support them anyway if you do not add this via a stored procedure implemented in .net).
string input = "A300-223100-0503-1";
Regex rgx = new Regex("^[^-]+-(.*)$");
string result = rgx.Replace(input, "$1");
Console.WriteLine(result);

Categories