user726049
user726049

Reputation:

Parse math operations with PHP

I am working on a project where I need to make a function that will parse the 4 default math operations (addition, subtraction, multiplication, division). It would be nice if the function could parse operations between brackets.

So, a must is that the function first check for multiplication and division operations (should check for that after it parser all operations between brackets if they exist, and that rule should apply for bracket operations [the biggest problem is that the brackets can contain brackets]). After doing all multiplication and division operations, it should do all addition and subtraction operations. The final number should be returned by functions.

Another nice addition would be a RegExp string that will check for math operations.

Thanks in advance!

Upvotes: 5

Views: 7139

Answers (7)

Anastas Dolushanov
Anastas Dolushanov

Reputation: 73

If the input does not include unary operators you can try this library I recently created: https://github.com/anastasd/expression-parser

Here is an example how to parse arithmetic expressions. The input does not need to be very well formatted:

$settings = new Settings(Settings::PHP);
$parser = new Parser($settings);
$input = ' ($a- 2.7182)* (3.1416+$b) / $c';

$output = $parser->parse($input, ['$a', '$b', '$c'])
  ->prepare()
  ->evaluate([1, 2, 3]);

// $output is -2.9447657066667

Instead of evaluating the input with numbers you can "compile" it in a function that can be saved in a file.

$settings = new Settings(Settings::PHP);
$parser = new Parser($settings);
$input = ' ($a- 2.7182)* (3.1416+$b) / $c';

$output = $parser->parse($input, ['$a', '$b', '$c'])
    ->prepare()
    ->compile(["compress"]);

// $output is 'function expressionResult( $a,$b,$c ){ return ($a-2.7182)*(3.1416+$b)/$c ;}'

You can easily create your own parser with just the four arithmetic operators. Please have a look at the examples with a custom parser.

Upvotes: -1

andig
andig

Reputation: 13906

I can recommend https://github.com/andig/php-shunting-yard which is a PSR-0 compatible implementation of the Shunting Yard algorithm.

Upvotes: 2

Henry
Henry

Reputation: 9

if you want a truly safe math parser, then eval won't do it. bcParserPHP can do it. It is implemented in PHP and does not use eval, thus it is very secure.

Upvotes: 0

Fivell
Fivell

Reputation: 11929

there was a similar problem
How to evaluate formula passed as string in PHP? you can try to use Class: Eval Math from php classes http://www.phpclasses.org/package/2695-PHP-Safely-evaluate-mathematical-expressions.html

Upvotes: 2

dave1010
dave1010

Reputation: 15445

This should be pretty secure:

function do_maths($expression) {
  eval('$o = ' . preg_replace('/[^0-9\+\-\*\/\(\)\.]/', '', $expression) . ';');
  return $o;
}

echo do_maths('1+1');

Upvotes: 6

Jimmy Sawczuk
Jimmy Sawczuk

Reputation: 13614

Regular expressions aren't the answer here; I suggest using an expression tree where all terminal nodes are constants or variables, and the rest of the nodes are operators. For example, 2 + 3 * 4 becomes:

+ --- 2
  |
  --- * --- 3
        |
        --- 4

Then, you evaluate the expression by using a depth-first traversal. In PHP it's sort of difficult to represent trees, but you could either use a built-in library as a commenter suggested or represent them using an associative array of arrays.

Upvotes: 0

Carlos Campderrós
Carlos Campderrós

Reputation: 23002

You could use eval() (WARNING: be sure what enters is a math operation and not some other arbitrary input or php code).

$input = "3 + (4 - 2 * 8) / 2";

eval('$result = ' . $input . ';');

echo "The result is $result";

Upvotes: 2

Related Questions