Say we have strings like:
string s1 = "a < 5";
string s2 = "b >= 7";
string s3 = "c <= 8";
...
I want to convert such strings into BinaryExpression objects similar to what we get by using:
BinaryExpression b1 = Expression.MakeBinary( ExpressionType.LessThan, Expression.Parameter( typeof( int ), "a" ), Expression.Constant( 5, typeof( int ) ) );
BinaryExpression b2 = Expression.MakeBinary( ExpressionType.GreaterThanOrEqual, Expression.Parameter( typeof( int ), "b" ), Expression.Constant( 7, typeof( int ) ) );
BinaryExpression b3 = Expression.MakeBinary( ExpressionType.LessThanOrEqual, Expression.Parameter( typeof( int ), "c" ), Expression.Constant( 8, typeof( int ) ) );
I have created the method below:
BinaryExpression ConvertStringToBinaryExpression( string exp )
{
string[] s = exp.Split( ' ' );
string param = s[ 0 ];
string comparison = s[ 1 ];
int constant = int.Parse( s[ 2 ] );
if ( comparison == "<" )
return Expression.MakeBinary( ExpressionType.LessThan, Expression.Parameter( typeof ( int ), param ), Expression.Constant( constant, typeof ( int ) ) );
else if ( comparison == "<=" )
return Expression.MakeBinary( ExpressionType.LessThanOrEqual, Expression.Parameter( typeof ( int ), param ), Expression.Constant( constant, typeof ( int ) ) );
else if ( comparison == ">" )
return Expression.MakeBinary( ExpressionType.GreaterThan, Expression.Parameter( typeof ( int ), param ), Expression.Constant( constant, typeof ( int ) ) );
else if ( comparison == ">=" )
return Expression.MakeBinary( ExpressionType.GreaterThanOrEqual, Expression.Parameter( typeof ( int ), param ), Expression.Constant( constant, typeof ( int ) ) );
else
throw new ArgumentException( "Invalid expression.", "exp" );
}
However, the above method does not work properly if, for example, we have strings like:
string s4 = "a< 5" // no space between 'a' and '<'
string s5 = "b>=9" // no space at all
string s6 = "c <=7" // no space betwen '<=' and '7'
What is the easiest way to make it more robust and reliable?
As Harsha pointed it out regex
would make your task simple
Match m=Regex.Match("var4 <= 433",@"(?'leftOperand'\w+)\s*(?'operator'(<|<=|>|>=))\s*(?'rightOperand'\w+)");
m.Groups["leftOperand"].Value;//the varaible or constant on left side of the operator
m.Groups["operator"].Value;//the operator
m.Groups["rightOperand"].Value;//the varaible or constant on right side of the operator
Use regex to match against some types of possible expressions (if you have an exhaustive and reasonably short list of possible expressions). Also parse the string if it does not match your regex to check for any unexpected chars.
EDIT: The regex and parse will help you "clean" the string before you can use your switch/if-else case.
http://www.c-sharpcorner.com/UploadFile/prasad_1/RegExpPSD12062005021717AM/RegExpPSD.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With