2

I want to check all brackets start and close properly and also check it is mathematical expression or not in given string.

ex :

$str1 = "(A1+A2*A3)+A5+(B3^B5)*(C1*((A3/C2)+(B2+C1)))"

$str2 = "(A1+A2*A3)+A5)*C1+(B3^B5*(C1*((A3/C2)+(B2+C1)))"

$str3 = "(A1+A2*A3)+A5++(B2+C1)))"

$str4 = "(A1+A2*A3)+A5+(B3^B5)*(C1*(A3/C2)+(B2+C1))"

In above Example $str1 and $str4 are valid string....

Please Help....

Chintan
  • 1,204
  • 1
  • 8
  • 22
  • Find an EOS library and either use the 'false' return of a conversion, or modify it to cut out and fail the way you want it to? – Jon Feb 02 '13 at 11:06
  • Thanks for reply but didn't got it. Please explain in details... – Chintan Feb 02 '13 at 11:11
  • Finding the matching braces is a typical task for recursive regex, google for it. – zerkms Feb 02 '13 at 11:12
  • 1
    There are a couple of 'Equation Operating Systems' that are written in PHP and fairly small in size that parse an equation to RPN or fail out silently (returning false) that you could use to quickly parse the equation with a tree structure and let you know if it was right. Or.. you could use recursive Regex. (Which... can get confusing unless you are fairly good at using it RegEx to begin with ^^) On a side note, you might want to check to brackets, ie '[]' as well as they are valid within expressions as well. – Jon Feb 02 '13 at 11:14
  • There exists [answer to the similar question][1]. Hope it'll help. And try to use [exprlib][2]. [1]: http://stackoverflow.com/questions/1015242/how-to-evaluate-formula-passed-as-string-in-php [2]: http://stackoverflow.com/questions/1015242/how-to-evaluate-formula-passed-as-string-in-php – Viacheslav Dobromyslov Feb 02 '13 at 11:18
  • How broad are you defining "mathematical expression"? Your examples just use the four basic arithmetic operations plus exponentiation, but that is not even close to basic maths: what about roots, trig functions, …. – Richard Feb 02 '13 at 11:47

3 Answers3

2

You'll need a kind of parser. I don't think you can handle this by a regular expression, because you have to check the amount and the order of parentheses and possible nested ones. This class below is quick PHP port of a Python based Math expression syntax validator of parentheses I found:

class MathExpression {

    private static $parentheses_open = array('(', '{', '[');
    private static $parentheses_close = array(')', '}', ']');

    protected static function getParenthesesType( $c ) {
        if(in_array($c,MathExpression::$parentheses_open)) {
            return array_search($c, MathExpression::$parentheses_open);
        } elseif(in_array($c,MathExpression::$parentheses_close)) {
            return array_search($c, MathExpression::$parentheses_close);
        } else {
            return false;
        }
    }

    public static function validate( $expression ) {
        $size = strlen( $expression );
        $tmp = array();
        for ($i=0; $i<$size; $i++) {
            if(in_array($expression[$i],MathExpression::$parentheses_open)) {
                $tmp[] = $expression[$i];
            } elseif(in_array($expression[$i],MathExpression::$parentheses_close)) {
                if (count($tmp) == 0 ) {
                    return false;
                }
                if(MathExpression::getParenthesesType(array_pop($tmp)) 
                    != MathExpression::getParenthesesType($expression[$i])) {
                    return false;
                }
            }
        }
        if (count($tmp) == 0 ) {
            return true;
        } else {
            return false;
        }
    }
}

//Mathematical expressions to validate
$tests = array(
    '(A1+A2*A3)+A5+(B3^B5)*(C1*((A3/C2)+(B2+C1)))',
    '(A1+A2*A3)+A5)*C1+(B3^B5*(C1*((A3/C2)+(B2+C1)))',
    '(A1+A2*A3)+A5++(B2+C1)))',
    '(A1+A2*A3)+A5+(B3^B5)*(C1*(A3/C2)+(B2+C1))'
);

// running the tests...
foreach($tests as $test) {
    $isValid = MathExpression::validate( $test );
    echo 'test of: '. $test .'<br>';
    var_dump($isValid);
}
axel.michel
  • 5,764
  • 1
  • 15
  • 25
  • 1
    That port in PHP only covers nested brackets/etc. It won't actually be able to validate if a string is a true mathematically valid function. (The original Python code is inadequate for the correct valuation of any inputted string you want to validate. – Jon Feb 02 '13 at 12:09
  • @Jon yes it only covers the brackets (part one of the question) in case you want to test the complete syntax you would need an eval of the expression, but for this, you'll need values. – axel.michel Feb 02 '13 at 12:12
  • You need the equivalent of an eval for it, but you don't need values for it if you find an infix to RPN parser. – Jon Feb 02 '13 at 12:13
  • 1
    @chintu As Jon mentioned it is only a check for correct brackets. I looked around a bit and found this answer: http://stackoverflow.com/a/1015281/1846918 this might cover your question completely. – axel.michel Feb 02 '13 at 12:34
  • it will not work if we have a expression like: (12.0000--++*-*+23.0000)-*34.0000 – Abhinav bhardwaj Jul 27 '17 at 10:19
1

Well I suppose that the thing, you are looking for, is some Context-free grammar or Pushdown automaton. It can not be done only using regular expressions. (at least there is no easy or nice way)

That is because you are dealing with nested structures. Some idea of an implementation can be found here Regular expression to detect semi-colon terminated C++ for & while loops

Community
  • 1
  • 1
Jendas
  • 3,359
  • 3
  • 27
  • 55
  • 1
    You link to a question who's accepted answer is a link to another question. Could you not just follow that for the SO poster? – Jon Feb 02 '13 at 12:04
-1

Use Regular Expression that returns you howmany Opening Brackets and Closing Brackets are there?

then check for the number of both braces....if it is equal then your expression is right otherwise wrong...

Vimal Patel
  • 607
  • 5
  • 19