Обнаружение отрицательных чисел с помощью Javascript для разработки калькулятора

Я разрабатываю распределенный калькулятор с использованием JavaScript и PHP. Калькулятор должен распознавать скобки и изменять порядок вычислений в соответствии со скобками. Все основные математические операции (*, /, +, -) имеют одинаковый приоритет (в отличие от общего приоритета). Я использую следующее регулярное выражение, чтобы получить пользовательский ввод и поместить в массив. Это регулярное выражение хорошо работает для положительных чисел:

/\d*\.\d+|\d+|[()/*+-]/g

Однако когда дело доходит до отрицательных чисел, происходит сбой, потому что я использую функцию рекурсивной замены, которая заменяет каждую пару скобок (и содержимое) результатом операций внутри этих скобок. Я делаю это, потому что это распределенный калькулятор, и я должен выполнять каждую атомарную операцию на стороне сервера, а затем возвращать результат обратно и показывать его в истории операций.

Все, что я хочу, это обнаружить отрицательные числа (чтобы сохранить их как один элемент в массиве). Я думаю, что это должно работать следующим образом: когда есть два последовательных оператора (с нулем или более пробелами между ними), а второй оператор является знаком минус (-), знак минус должен быть объединен со следующим числом (как знак числа). Кроме того, если первому числу предшествует знак минус, знак должен быть присоединен к этому числу.


person Javad    schedule 20.02.2013    source источник


Ответы (1)


Поскольку в реализации регулярных выражений в javascript нет обратной связи, это не так просто, как кажется на первый взгляд.

Это один из способов сделать это. Предполагается, что пробелы были удалены в первую очередь.

var m,
    tokens = [],
    rex = /(^|[(\/*+-])(-(?:\d*\.)?\d+)|[()\/*+-]|(?:\d*\.)?\d+/g,
    str = '-4-(-2*3)--4-2/-0.9-3+(3-4*-4)';

while ( m = rex.exec( str ) ) {
    if ( m[1] ) {
        tokens.push( m[1], m[2] );
    } else {
        tokens.push( m[0] );
    }
}

console.log( tokens );
// [ "-4", "-", "(", "-2", "*", "3", ")", "-", "-4", "-", "2", "/", "-0.9", "-", "3", "+", "(", "3", "-", "4", "*", "-4", ")" ]

Здесь обратная связь эмулируется с использованием групп захвата (). Если перед отрицательным числом m[2] стоит начало строки ^ или оператор m[1], то в массив добавляются и оператор, и отрицательное число. В противном случае любой - добавляется в массив как оператор.

В качестве альтернативы вы можете использовать

tokens = str.match( /(?:\d*\.)?\d+|[()\/*+-]/g );

а затем выполните итерацию по массиву, и если вы найдете - после оператора, добавьте его к следующему номеру.

Каким бы способом вы это ни делали, простое регулярное выражение не будет токенизировать только строку, вам нужно будет использовать условный оператор, чтобы определить, как обрабатывать каждый -.

person MikeM    schedule 24.02.2013