I have a method that needs to return true or false based upon a string expression that is passed in to it. The string expression could look like:
("ASDF"=="A" || "BED"!="BED") && (5>=2)
or any valid C# expression that evaluates to a Boolean result. I only need to support basic string and math comparison operators plus parentheses. I have tried NCalc but when I pass it this:
"GEN"=="GEN" || "GEN"=="GENINTER"
it generates the error
System.ArgumentException: Parameter was not defined (Parameter 'GEN')
at NCalc.Domain.EvaluationVisitor.Visit(Identifier parameter)
when I use the following code:
NCalc.Expression e = new(filterExpression, EvaluateOptions.IgnoreCase);
var filterResultObject =e.Evaluate();
Any thoughts appreciated on how to evaluate an arbitrary expression since I will not know the expression until run time.
Greg
I have found that NCalc will properly evaluate the strings but only if they are single quoted such as !('GEN'=='GEN'). If the strings are double quoted, the error is thrown.
For your example you can use NFun package like this:
string str = "\"ASDF\"==\"A\" || \"BED\"!=\"BED\") && (5>=2)"
bool result = Funny.Calc<bool>(str)
Related
According to MSDN String.Format throws if format is null (pretty reasonable), link here.
But testing says it only does that if the second argument is null as well, not if the second one is populated.
The following does not throw:
string test = string.Format(null, "string");
The following throws complaining about the first parameter (format):
string test = string.Format(null, null);
Digging futher with JustDecompile the source code calls the following method:
private static string FormatHelper(IFormatProvider provider, string format, ParamsArray args)
{
if (format == null)
{
throw new ArgumentNullException("format");
}
return StringBuilderCache.GetStringAndRelease(StringBuilderCache.Acquire(format.Length + args.Length * 8).AppendFormatHelper(provider, format, args));
}
Which makes no sense as format is null and no exception is thrown. Any hints?
Ah, the joys of overload resolution. In that case, you're actually calling string.Format(IFormatProvider, string, params object[]) - so you're passing a null argument for the provider parameter, which is entirely valid (and means to use the current culture).
That overload is "better" because the conversion of the second argument from string literal to string is better than the conversion from string literal to object.
If you use argument names to force the right overload, load this:
string text = string.Format(format: null, arg0: "string");
... then it throws an exception as expected.
This question already has answers here:
Ternary with boolean condition in c#
(7 answers)
Closed 5 years ago.
I can't wrap by head around this even though I've read many stackoverflow threads.
I check if the page has a specific property value like so:
bool categoryCount = CurrentPage.HasValue("blogCategories");
I want to transform this into a one-line if statement so I can parse a string to a class like illustrated below:
string situation = (categoryCount.ToString() == "true") ? '' : '';
PS: I apologize for the missing logic behind my thoughts/goal. I'm new at programming.
What about:
string situation = (CurrentPage.HasValue("blogCategories"))
? "Has the value" : "Has NOT that value";
You should change two things:
do not work with ToString() == "True", simply put the boolean (expression) in the condition part of the ternary operator: it is inefficient to call ToString() and furthermore if the specifications change, it might stop working (actually true.ToString() returns "True", with a capital, so it will not work with your code);
use string literals "some string", not char literals 'a': the result is supposed to be a string, not a char.
By comparing with "true", this will not work:
csharp> true.ToString()
"True"
csharp> true.ToString() == "true"
false
But even if it would work, it would be rather unsafe: if later the designers of the .NET library change their minds, then your program could stop working correctly. Usually I think it is better not to rely on the format of a ToString() method. These tend to be culture specific, and furthermore usually do not offer hard constraints with respect to the output format anyway.
You don't need to convert to string to use ternary. You can simply just do this:
string situation = categoryCount ? "Executes if true" : "Executes if false";
The ternary condition doesn't need to be a string, just the returns.
You don't need to convert a bool to a string to find out if it's true.
Do you know what this returns if categoryCount has the boolean value true?
bool x = categoryCount.ToString() == "true";
It returns the boolean value true. If categoryCount is true, then it is true that its string representation is equal to "true". But categoryCount is true already.
It is exactly the same as this:
bool x = categoryCount;
Also, a string in C# uses double quotes, not single quotes.
So:
string situation = categoryCount ? "one string" : "another string";
I have been around in circles with this one and need some help. I have a method that evaluates code, so if I pass this Eval("DateTime.Now.Year - 1986") it returns 29, its working great and this means I can have inline code in my posts that dynamically evaluate at runtime (this might present some security concerns, but that for some other time), here's the example string I am trying to work with: string inStr = "this year is [EVAL]DateTime.Now.Year[/EVAL] and it has been [EVAL]DateTime.Now.Year - 1986[/EVAL] years since 1986"; I need a regex that will replace all [EVAL] instances and return the full text with the evaluated results. Anyone?
You want a Regex, you can have a regex...
string inStr = "this year is [EVAL]DateTime.Now.Year[/EVAL] and it has been [EVAL]DateTime.Now.Year - 1986[/EVAL] years since 1986";
var rx = new Regex(#"(\[EVAL\])(.*?)(\[/EVAL])");
string outStr = rx.Replace(inStr, RegexReplacer);
with
public static string RegexReplacer(Match match)
{
return Eval(match.Groups[2].Value);
}
or depending on the return type of Eval:
public static string RegexReplacer(Match match)
{
object obj = Eval(match.Groups[2].Value);
return obj != null ? obj.ToString() : string.Empty;
}
The capture group #2 is the (.*?). Note the use of the lazy quantifier .*?, because otherwise the capture would be [EVAL]DateTime.Now.Year[/EVAL] and it has been [EVAL]DateTime.Now.Year - 1986[/EVAL]
I have a string and I want to check if it contains any invalid filename characters. I know I could use
Path.GetInvalidFileNameChars
to get a array of invalid filename characters and loop through to see if the string contains any invalid char. But is there a easier and shorter expression? It is c#. So can anyone help?
bool containsInValidFilenameCharacters(string str) {
return str.Any(Path.GetInvalidFileNameChars().Contains)
}
Note that this is the same as doing
var invalidChars = Path.GetInvalidFileNameChars();
return str.Any(c => invalidChars.Contains(c));
But since the type signature of Contains matches up exactly with the parameter delegate type of Any we can just pass it directly and it will do an implicit conversion.
I am creating quite a complex query for mongodb within .net using C#. To do this I am building the query as a string then parsing it to get a QueryDocument:
var Q = new QueryDocument(BsonDocument.Parse(QueryString))
My problem is that part of the query contains a regex:
{""Str.tagkw"":{$regex : "" \\b(rasberry|ice cream|sweeties)\\b ""}}
After parsing the $regex part has been removed when I look at the query Q (as above)
Any help would be welcome.
Your code appears to work for me:
string queryString = #"{""Str.tagkw"":{$regex : "" \\b(rasberry|ice cream|sweeties)\\b ""}}";
var Q = new QueryDocument(BsonDocument.Parse(queryString));
When you look at this in an IDE such as Visual Studio, it will be displayed as
{ "Str.tagkw" : / \b(rasberry|ice cream|sweeties)\b / }
That's the Javascript representation: In Javascript, you can create regular expressions using either
var regex = new RegExp("(foo|bar)");
or, as syntactic sugar
var regex = /(foo|bar)/;
The ToString method which will be used by the debugger seems to prefer the second representation, but that's just a matter of how it's displayed.