Matching math expression with regular expression?

前端 未结 8 2133
旧时难觅i
旧时难觅i 2020-11-27 18:36

For example, these are valid math expressions:

a * b + c
-a * (b / 1.50)
(apple + (-0.5)) * (boy - 1)

And these are invalid math expression

8条回答
  •  一个人的身影
    2020-11-27 19:03

    This is tricky with one single regular expression, but quite easy using mixed regexp/procedural approach. The idea is to construct a regexp for the simple expression (without parenthesis) and then repeatedly replace ( simple-expression ) with some atomic string (e.g. identifier). If the final reduced expression matches the same `simple' pattern, the original expression is considered valid.

    Illustration (in php).

    function check_syntax($str) {
    
        // define the grammar
        $number = "\d+(\.\d+)?";
        $ident  = "[a-z]\w*";
        $atom   = "[+-]?($number|$ident)";
        $op     = "[+*/-]";
        $sexpr  = "$atom($op$atom)*"; // simple expression
    
        // step1. remove whitespace
        $str = preg_replace('~\s+~', '', $str);
    
        // step2. repeatedly replace parenthetic expressions with 'x'
        $par = "~\($sexpr\)~";
        while(preg_match($par, $str))
            $str = preg_replace($par, 'x', $str);
    
        // step3. no more parens, the string must be simple expression
        return preg_match("~^$sexpr$~", $str);
    }
    
    
    $tests = array(
        "a * b + c",
        "-a * (b / 1.50)",
        "(apple + (-0.5)) * (boy - 1)",
        "--a *+ b @ 1.5.0",
        "-a * b + 1)",
        "a) * (b + c) / (d",
    );
    
    foreach($tests as $t)
        echo $t, "=", check_syntax($t) ? "ok" : "nope", "\n";
    

    The above only validates the syntax, but the same technique can be also used to construct a real parser.

提交回复
热议问题