#!/usr/bin/perl use strict; use warnings; my $formula = '((1 + 2) * (2 -1)) + (2 * 3) + 5'; my %hash = ('*' => \&mal, '-' => \&minus, '+' => \&plus, '/' => \&div,); while($formula =~ s/\(([^\(]*?)\)/calc($1)/eg){ } print calc($formula); sub calc{ my ($part) = @_; while($part =~ s!(\d+)\s*([\*\/])\s*(\d+)!subcalc($1,$2,$3)!eg){}; while($part =~ s!(\d+)\s*([\+\-])\s*(\d+)!subcalc($1,$2,$3)!eg){}; return $part; } sub subcalc{ my ($op1,$op,$op2) = @_; return 0 unless exists($hash{$op}); return $hash{$op}->($op1,$op2); } sub mal{ my ($op1,$op2) = @_; return $op1 * $op2; } sub minus{ my ($op1,$op2) = @_; return $op1 - $op2; } sub plus{ my ($op1,$op2) = @_; return $op1 + $op2; } sub div{ my ($op1,$op2) = @_; return $op1 / $op2; }