【发布时间】:2015-05-28 05:04:59
【问题描述】:
我正在用 javascript 制作一个解析器,它将一个数学表达式作为一个字符串提供给脚本,并对其进行评估并用它做一些其他的事情。如果用户想使用内置的 Javascript 数学函数,他们必须输入以下字符串,例如“1 + Math.log(x)”。当事情嵌套时,这变得非常乏味,例如“Math.abs(Math.log(Math.pow(x, 2))) + Math.log2(x)”。如您所见,“数学”。它的一部分不仅需要更长的时间来编写,而且会降低可读性。我想删除那个“数学”。部分。我这样做的方法是使用简单的正则表达式,它基本上有一个所有 Javascript 数学常量和方法的列表,并且只是在“数学”前面加上。一部分。很简单:
input = input.replace(/(E|PI|SQRT2|SQRT1_2|LN2|LN10|LOG2E|LOG10E)/g, "Math.$1");
同样的事情发生在方法上。这工作正常。但与往常一样,这不是很灵活,并且留下了误解的空间,有人可能会昏迷并坚持输入 Math.log(x),而这又会被 Math.Math.log(x) 替换,这将不起作用。
我想知道的是,是否有某种方法可以匹配任何这些预定义字符串(常量和方法),以便只有在没有“数学”的情况下才能通过正则表达式匹配它们。部分在它前面。这个我试过了
^(?!Math\.)(log2|log|exp|abs)
但它毫无用处,因为它不适用于嵌套甚至多个操作数。有没有办法纯粹在正则表达式中做到这一点,因为这会使整个过程更加优雅。任何帮助将不胜感激。
【问题讨论】:
-
先做这个怎么样?
input.replace(/\bMath\./g,'')然后执行添加它的正则表达式。 -
如果用户在您的列表之外的某些内容中出现免费类型会发生什么?这是允许用户输入他们的公式的一种非常糟糕的方式。除非您完全解析每个最后一个字符的有效性,否则我不会这样做。如果您懒惰,请列出他们可以从中选择的函数和/或操作的下拉列表。
-
那肯定行得通,但不会很优雅,在一行内完成所有操作似乎更干净。给出的答案以非常干净的方式完全符合我的要求。
-
这个特定的脚本只生成一个用于其他解析器的 URL。它对外部世界没有影响,也可以访问任何数据。无论任何人可能会在那里插入任何恶意代码,如果他们只是打开他们的 JS 控制台并在那里输入恶意代码,效果也不会有所不同。安全性在这里不是问题,但我同意,评估原始输入通常是不好的做法。
标签: javascript regex