简体   繁体   中英

Evaluate boolish expression string at runtime

How can I evaluate expression string that look like the following examples? I'm looking for an easy way to parse them.

string1: "True and False"
bool: false

string1: "False and False"
bool: false

string1: "true or False"
bool: true

As long as it will always follow the simple structure given in your examples, this will work:

private static readonly Regex boolParseRegex =
    new Regex(@"^(true|false) (and|or) (true|false)$", RegexOptions.IgnoreCase);
public bool ParseExpression(string expr)
{
    var res = boolParseRegex.Match(expr);
    bool val1 = bool.Parse(res.Groups[1].Value);
    bool isAnd = string.Equals(res.Groups[2].Value, "and",
                               StringComparison.InvariantCultureIgnoreCase);
    bool val2 = bool.Parse(res.Groups[3].Value);
    return isAnd ? val1 && val2 : val1 || val2;
}

If you want to be able to parse more general expressions (eg "true" , "(true and false) or true" , in addition to "false and true" ), you should take a look at Irony , as recommended in convert string expression to a boolean expression 's answer (thanks to Frode for commenting that).

What you want may be achieved if you implement a parser, or use a parsing library. Basically you need to break down your expression to its components, and then interpret them as logic blocks; your samples contain two types, values and operators.

Let's try it on your first example, True AND False :

 True  <- value     : Carry it over
 AND   <- operator  : store
 False <- Value     : Use stored Operation on Carried value. Carry it over.
 End of expression

Things get a tad more complicated if you add grouping, because you need to store sequences in a structure often called an expression tree , because it's hierarchical and require you to parse each group, starting from the 'leaves' (furthest away from the root). Let's use the following example:

False XOR (True AND False) OR (True OR False)

The expression tree would look like this:

  Root Group        : False XOR G1 OR G2
    Group 1         : True AND False
    Group 2         : True OR False

Using your expression evaluator, you need to first solve groups 1 and 2:

  Root Group        : False XOR G1 OR G2
    Group 1         : False
    Group 2         : True

Then apply it to the Root group:

Root Group          : False XOR False OR True

 False <- value     : Carry it over
 XOR   <- operator  : store
 False <- value     : Apply stored Operation (result True). Carry it over.
 AND   <- operator  : store
 False <- Value     : Apply stored Operation (result True). Carry it over.
 - End of expression

That's basically how expression parsers works.

Edit: Irony , pointed out by Frode on a comment on your question, is a well-known language parser that might do the trick for you. I remember reading about it a while ago, but he was way faster than me. =)

something simple could be:

static bool string_parser(string str_to_parse)
        {
            bool result= false;
            string[] parts = str_to_parse.Split(' ');
            if (parts.Length == 3)
            {
                if (parts[0].ToLower().Contains("true"))
                {
                    result = true;
                }
                if (parts[1].ToLower().Contains("or"))
                {
                    if (parts[2].ToLower().Contains("true"))
                    {
                        result= result || true;
                    } 
                }
                else if (parts[1].ToLower().Contains("and"))
                {
                    result = parts[2].ToLower().Contains("true") ? result && true : result && false;
                }
            }
            return result;
        }

but I wonder False && False should not be 'True' in this example false && false is false

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM