如何解析包含计算的字符串并执行它

时间:2018-12-11 10:29:43

标签: javascript vuejs2

我有以下情况

所以我有一个类似这样的对象

var y = {
  "data": {
    "m": 2,
    "n": "meaow",
    "k": "lop",
    "r": {
      "val": 400,
      "text": "Hoila papi"
    }
  }
}

现在我想给我的用户写一个公式,我可以根据该对象进行解析 像这样

var  x = {
            "calculation": "((@data>m# * 100) + (@data>r>val# / 200))",
            "target": "data>m"
 }

有没有办法在Javascript中做到这一点 所以最终结果应该是

{
  "data": {
    "m": 202,
    "n": "meaow",
    "k": "lop",
    "r": {
      "val": 400,
      "text": "Hoila papi"
    }
  }
}

1 个答案:

答案 0 :(得分:1)

使用正则表达式匹配@prop>prop...字符串,并通过在属性数组上使用reduce将它们替换为适当的值。假设输入是可信的,则可以eval生成的数学字符串,并使用相同的reduce方法来查找要更新的嵌套对象。

请注意,((200 * 100) + (400 / 200))产生的是20002,而不是202

var y = {
  "data": {
    "m": 200,
    "n": "meaow",
    "k": "lop",
    "r": {
      "val": 400,
      "text": "Hoila papi"
    }
  }
}

var x = {
  "calculation": "((@data>m# * 100) + (@data>r>val# / 200))",
  "target": "data>m"
};
const getNested = (propArr, initial) => propArr.reduce((a, prop) => a[prop], initial);
const mathStr = x.calculation.replace(/@(\S+)#/g, (_, propStr) => (
  Number(getNested(propStr.split('>'), y))
));
console.log(mathStr);
if (/[^-+/*0-9() ]/.test(mathStr)) {
  throw new Error('Unrecognized, potentially unsafe character found');
}

const targetPropArr = x.target.split('>');
const lastProp = targetPropArr.pop();
const lastObj = getNested(targetPropArr, y);
lastObj[lastProp] = eval(mathStr);

console.log(y);