2016-09-05 5 views
0

Я пытаюсь разобрать математику в строках. Он работает для x * y, но не x*y*z. Я думаю, что это связано с одной строкой, а другая - числом. Но я не могу найти способ обойти это.Regex не соответствует номерам

Вот мой код:

var reMD = /(\d+) *[\*|\/] *(\d+)/g 
var str = '17 * 13 * 4'; 
var ex; 
runWhile(); 

function runWhile() { 
    var ex = reMD.exec(str); 
    if (ex !== null) { 
    if (ex.index === reMD.lastIndex) { 
     reMD.lastIndex++; 
    } 
    if (ex[0].indexOf('*') !== -1) { 
     var rep = parseInt(ex[1]) * parseInt(ex[2]) 
    } else { 
     var rep = parseInt(ex[1])/parseInt(ex[2]) 
    } 
    var rep = rep.toString() 
    str = str.replace(ex[0], rep) 
    if (reMD.exec(str) !== null) { 
     runWhile() 
    } 
    } 
} 
alert(str) 

Оповещение посылает обратно 221 * 4, но он должен вернуться в 884. Как я могу это исправить?

+0

Как бы это исправить, так что видит его как '221 * 4' второй раз' Exec() 'называется? – Hawkeye

ответ

1

Он должен работать, если вы удалите флаг g из своего регулярного выражения, потому что тогда каждый раз, когда вы вызываете .exec(), он начнет заново, как объяснено at MDN. Вы также можете удалить код, который возится с reMD.lastIndex.

g флагом, он пытается сопоставить с индексом, где предыдущий матч закончился, но вы пытаетесь соответствовать против новой строки.)

Заметим также, что вы могли бы изменить регулярное выражение для поиска оператор тоже, а не с помощью indexOf(), и вы на самом деле не нужно вызывать parseInt() потому * и / операторы будут принуждать операнды к номерам:

var reMD = /(\d+) *([\*|\/]) *(\d+)/ 
 
var str = '17 * 13/4'; // note I've change the input to demostrate * and/
 
runWhile(); 
 

 
function runWhile() { 
 
    var ex = reMD.exec(str); 
 
    if (ex !== null) { 
 
    if (ex[2]==="*") { 
 
     var rep = ex[1] * ex[3] 
 
    } else { 
 
     var rep = ex[1]/ex[3] 
 
    } 
 
    rep = rep.toString() 
 
    str = str.replace(ex[0], rep) 
 
    if (reMD.exec(str) !== null) { 
 
     runWhile() 
 
    } 
 
    } 
 
} 
 
console.log(str)

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

0

я не знаю, если это будет достаточно для вашего проекта, но он работает

'17 * 13 * 4'.replace(/(\d+)(*[\*|\/] *(\d+))*/g, eval) 
Смежные вопросы