Вот несколько подробный код, который я откатил для еще один вопрос .Он соответствует BO MDAS без eval()
, но не оборудован для выполнения сложных / более высокого порядка / круглых выражений.Этот безбиблиотечный подход разделяет выражение и систематически уменьшает массив компонентов, пока не будут удалены все операторы.Это, безусловно, работает для вашего примера выражения: 2-1
;)
preg_match()
проверяет, что у каждого оператора есть числовая подстрока на каждой стороне. preg_split()
делит строку намассив чередующихся чисел и операторов. array_search()
находит индекс целевого оператора, пока он существует в массиве. array_splice()
заменяет элемент оператора и элементы либосторона с новым элементом, который содержит математический результат удаления трех элементов.
** обновлен, чтобы разрешить отрицательные числа **
Код: ( Demo )
$expression="-11+3*1*4/-6-12";
if(!preg_match('~^-?\d*\.?\d+([*/+-]-?\d*\.?\d+)*$~',$expression)){
echo "invalid expression";
}else{
$components=preg_split('~(?<=\d)([*/+-])~',$expression,NULL,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
var_export($components); // ['-11','+','3','*','1','*','4','/','-6','-','12']
while(($index=array_search('*',$components))!==false){
array_splice($components,$index-1,3,$components[$index-1]*$components[$index+1]);
var_export($components);
// ['-11','+','3','*','4','/','-6','-','12']
// ['-11','+','12','/','-6','-','12']
}
while(($index=array_search('/',$components))!==false){
array_splice($components,$index-1,3,$components[$index-1]/$components[$index+1]);
var_export($components); // [-'11','+','-2','-','12']
}
while(($index=array_search('+',$components))!==false){
array_splice($components,$index-1,3,$components[$index-1]+$components[$index+1]);
var_export($components); // ['-13','-','12']
}
while(($index=array_search('-',$components))!==false){
array_splice($components,$index-1,3,$components[$index-1]-$components[$index+1]);
var_export($components); // [-25]
}
echo current($components); // -25
}
Вот демонстрационная версия B OMDAS , которая использует php's pow()
, когда между 10 числами встречается ^
или отрицательно).
Не думаю, что когда-нибудь буду писать версию, которая обрабатывает выражения в скобках ... но мы увидим, как мне скучно.