【问题标题】:Regex replace everything not starting with multiple times in line正则表达式替换所有不以多次开头的内容
【发布时间】: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


【解决方案1】:

您可以使用以下技巧,以便即使匹配或不匹配也会被替换:

(?:Math\.)?(log2|log|exp|abs|pow)

并替换为Math.$1

DEMO

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    相关资源
    最近更新 更多