马黑黑 发表于 2024-1-2 08:59

JS+正则:构建算式

本帖最后由 马黑黑 于 2024-1-2 09:01 编辑

假如我们有一个算术的式子,例如像下面酱紫:

11+(22/8)

或酱紫:

11+(22/8)-798

现在,我们要将式子中的最后一部分变为平方值。目标是酱紫:

11+(22/8)²
11+(22/8)-798²

在变之前,我们得判断最后一部分是数字(如上面例二的 798)还是一个子算式(如上面例一的 (22/8)),因为二者的平方计算式子,构造方法不同。我们可以利用正则表达式来做一揽子的工作。

先从简单的开始,匹配末尾出现的连续的数字,正则表达式为:

(\d)+$

\d 是数字,我们用小括号将其包裹起来,这里是为了避免产生歧义。$ 表示行末(或一个字串的结尾)。

再匹配末尾出现的小括号对,我构建的匹配式子如下:

(\(+\))$

解释下:最外层小括号,是为了将来引用而加入的,这里只分析红色部分。\( 表示小括号开始,小括号是正则保留字符,要用 \ 转义,后续的加减乘除符号也酱紫转义;+ 的意思是,数字和 +-*/ 出现一次或多次;\) 表示小括号收尾。加上 $ 限制了行末位置,这就可以匹配子算式了。

然后可以将上面两个正则用 | 连缀起来一用使用,| 表示 或者的意思,含义与JS的 || 一样。

下面是完整的示例,可以改变待转换式子查看效果:

<div id="mydiv"></div>

<script>

let str = '11+(22/8)'; /* 待检测算式 */
let strRes;

let regex = /(\(+\))$|((\d)+)$/g;
if(regex.test(str)) {
      strRes = str.match(regex);
      str = str.replace(regex,'$1²');
}

mydiv.innerText = str;

</script>


这里只是一个个例,不过可以举一反三,或可给实际应用一些启发。

马黑黑 发表于 2024-1-2 09:03

当然,上面例子处理不了复杂的子算式:假设行末出现的子算式是小括号嵌套,则需要另外构建正则。

侃大山 发表于 2024-1-2 09:21

路过,看不懂{:5_106:}

红影 发表于 2024-1-2 10:32

里面最后的/ 是什么含义?

红影 发表于 2024-1-2 10:33

正则里的转义符是看着最头晕的,一堆转义符看得晕头晕脑{:4_173:}

红影 发表于 2024-1-2 10:38

黑黑构建了匹配式子,就可以让人绕开恼人的转义符,直接使用公式了吧。这样真好。{:4_187:}
去运行了一下,结果显示11+(22/8)²

马黑黑 发表于 2024-1-2 11:53

红影 发表于 2024-1-2 10:38
黑黑构建了匹配式子,就可以让人绕开恼人的转义符,直接使用公式了吧。这样真好。
去运行了一下 ...

这个式子的外观其实容易造成迷惑,我这里只是举例。事实上,计算机要运算 8² 或 (8*5-1)²,以JS为例,它要这样做:

Math.pow(8,2)
Math.pow((8*5-1),2)

所以,一楼讨论的匹配纯数字和子算式是非常有必要的,而不是简单的字串加上一个幂符号

马黑黑 发表于 2024-1-2 11:55

红影 发表于 2024-1-2 10:32
里面最后的/ 是什么含义?

除号 /

马黑黑 发表于 2024-1-2 11:56

侃大山 发表于 2024-1-2 09:21
路过,看不懂

这个确实不好懂的,很多程序员都晕正则

马黑黑 发表于 2024-1-2 11:56

红影 发表于 2024-1-2 10:33
正则里的转义符是看着最头晕的,一堆转义符看得晕头晕脑

即便没有转义符,正则都是难懂的

红影 发表于 2024-1-2 16:49

马黑黑 发表于 2024-1-2 11:53
这个式子的外观其实容易造成迷惑,我这里只是举例。事实上,计算机要运算 8² 或 (8*5-1)²,以 ...

嗯嗯,都把它规定好了,才能让运算公式被接受。

红影 发表于 2024-1-2 16:53

马黑黑 发表于 2024-1-2 11:55
除号 /

哦哦,知道了,是0-9的数字和加减乘除的四个符号都包括在内。
“$ 表示行末”这个也挺难懂的,括号里的那些都算行末么?

红影 发表于 2024-1-2 16:53

马黑黑 发表于 2024-1-2 11:56
即便没有转义符,正则都是难懂的

这个不知道到后面新的东西出来,会不会被简化{:4_173:}

马黑黑 发表于 2024-1-2 19:18

红影 发表于 2024-1-2 16:53
这个不知道到后面新的东西出来,会不会被简化

正则已经很简化了

马黑黑 发表于 2024-1-2 19:19

红影 发表于 2024-1-2 16:53
哦哦,知道了,是0-9的数字和加减乘除的四个符号都包括在内。
“$ 表示行末”这个也挺难懂的,括号里的 ...

不是。$ 就是行末,它放在那里,表示行末。

马黑黑 发表于 2024-1-2 19:20

红影 发表于 2024-1-2 16:49
嗯嗯,都把它规定好了,才能让运算公式被接受。

意思是先检测是数字还是子算式,然后做别的处理。当然了,我这个还是经不起推敲,比如,没有考虑纯数字有可能是浮点数。

红影 发表于 2024-1-2 19:48

马黑黑 发表于 2024-1-2 19:18
正则已经很简化了

它能变插件才好{:4_173:}

红影 发表于 2024-1-2 19:48

马黑黑 发表于 2024-1-2 19:19
不是。$ 就是行末,它放在那里,表示行末。

截止到哪里算是行末呢?

红影 发表于 2024-1-2 19:49

马黑黑 发表于 2024-1-2 19:20
意思是先检测是数字还是子算式,然后做别的处理。当然了,我这个还是经不起推敲,比如,没有考虑纯数字有 ...

这个已经很厉害了,对这个很陌生,黑黑却是做深入的研究{:4_187:}

马黑黑 发表于 2024-1-2 20:29

红影 发表于 2024-1-2 19:49
这个已经很厉害了,对这个很陌生,黑黑却是做深入的研究

因为用到
页: [1] 2 3 4 5
查看完整版本: JS+正则:构建算式