Javascript 正则表达式删除涉及零或一的冗余乘法/除法?

Javascript 正则表达式删除涉及零或一的冗余乘法/除法?,javascript,regex,Javascript,Regex,我有一个奇怪的问题,我收到计算机生成的方程(作为一个字符串),其中偶尔会出现零或一和孤立零的乘法/除法。这些方程式将以字符串形式呈现给用户 我知道我可以通过实现一种解析器来删除等式中的这些冗余部分,但我很好奇是否可以使用正则表达式来删除它们 在我最终放弃(相当有限的)正则表达式技能之前,我想到了以下几点: /([^\+\-]*(?:0|0\*|\*0){1,}[^\+\-]*)|(?:1\*|\*1)/g 似乎只有在以下情况下才有效: 没有带零的非零数字(如10、20等) 没有否定 它也不

我有一个奇怪的问题,我收到计算机生成的方程(作为一个字符串),其中偶尔会出现零或一和孤立零的乘法/除法。这些方程式将以字符串形式呈现给用户

我知道我可以通过实现一种解析器来删除等式中的这些冗余部分,但我很好奇是否可以使用正则表达式来删除它们

在我最终放弃(相当有限的)正则表达式技能之前,我想到了以下几点:

/([^\+\-]*(?:0|0\*|\*0){1,}[^\+\-]*)|(?:1\*|\*1)/g
似乎只有在以下情况下才有效:

  • 没有带零的非零数字(如10、20等)
  • 没有否定
它也不能很好地处理括号。不幸的是,括号很常见

请注意,删除上述冗余部分可能会导致冗余括号或“零”括号(即它可能变成类似
()*x
,相当于
0*x
)。多余的括号并不是一个大问题,但我假设“零”括号可以通过第二遍删除,类似于第一遍查找
()
。如果这两种方法中的任何一种都能在解决这个问题的正则表达式中实现,我会印象深刻

所以我转向你们,堆栈溢出的正则表达式大师。能做到吗

假设 关于字符串化方程,可以假设以下情况为真:

  • 不存在被零除的情况,方程式将不会出现任何
    [expr]/0
    ,甚至不会出现计算结果为
    [expr]/0
    的表达式,例如
    [expr]/sin(0)
  • 方程式中唯一的运算符是
    +
    -
    *
    /
  • 减号运算符(
    -
    )包括减法和求反运算,尽管求反运算总是用括号括起来
  • 除上述操作以外的任何操作(
    sin
    cos
    pow
    等)都将显示为函数调用。(无
    ^
    %
    等)
样本方程
非常混乱,不是吗?

在留下评论后,我忍不住要尝试一下:)

最大的问题是嵌套括号。正则表达式本身在处理嵌套结构方面非常糟糕。这是我口头禅“正则表达式是一种工具,而不是解决方案”的一个主要例子

使用正则表达式作为工具,可以对这种树结构应用某种“叶优先”(或自底向上)方法,这就是我在第一部分
中所做的,而(sEq.match(…){…}
。之后,我可以遍历创建的
数组
,并进行一些简单的文本编辑

我还添加了
1*
*1
/1
被删除,因为它们同样不会影响等式。您可能可以扩展它,使其足够智能,分别用
0
1
替换
sin(0)
/
cos(0)
,然后在某些情况下解决方案会更小

(正如代码注释中提到的,如果等式中包含
5.0*4
之类的内容,则会出现这种情况,因为JavaScript正则表达式没有lookbehind,所以我相信
\b
单词边界可以帮我完成这项工作。只需添加删除不必要小数的逻辑就可以解决这个问题。类似
sEq=sEq.replac的东西e(/\.0+\b/g,);
但我不知道这对于您的用例是否是必要的。)Edit:now fixed,
5.0*4
应该保持不变

但这并没有经过彻底测试,欢迎反馈

(0+(0/0.0/0.5+0+1*cos(p)++0*0+0+0+0*0*正宗(p)p)中金(k)+(0+1+1*0+0+1*0+0+0+0*0+0+0*0+0+0+0+0*1*0+0+0*1*1+0+0*1*1+0*1+1+0*1+1+1+0*1+0*1+0+0*1+0+0+0+0*1+0+0*0*0+0*0*0*0*0+0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0*0**0+0*sin(p))*0+(0+1*0+0*1+0*0)*0+(0+1*(-sin(p))/0.5+0*0+0*cos(p))*1*z); var Apart=[]; document.getElementById('output')。value=sEq+'\n'; while(sEq.match(/\([^()]*\)/){ //当仍有“leaf”时,将其保存到apart并替换为 //在Apart中对其索引的引用,使其父项成为新的索引 //“叶”,因为它现在不再包含圆括号 sEq=sEq.replace(/([a-z]*)\([^()]*)\)/gi,函数(m,f,a){ var n=一部分长度; 公寓[n]={ “发现”:m, “funct”:f, “arith”:一个 }; 返回'['+n+']'; }); } 对于(变量i=0;i"(0+(0/0.5+(0+1*cos(p)+0*0+0*sin(p))*cos(k)+(0+1*0+0*1+0*0)*(-sin(k))+(0+1*(-sin(p))/0.5+0*0+0*cos(p))*0)*x+(0+(0+1*cos(p)+0*0+0*sin(p))*sin(k)+(0+1*0+0*1+0*0)*cos(k)+(0+1*(-sin(p))/0.5+0*0+0*cos(p))*0)*y+(0+(0+1*cos(p)+0*0+0*sin(p))*0+(0+1*0+0*1+0*0)*0+(0+1*(-sin(p))/0.5+0*0+0*cos(p))*1)*z)"