【问题标题】:regexp to match basic arithmetic with letters and put them in groups [duplicate]正则表达式将基本算术与字母匹配并将它们分组[重复]
【发布时间】:2020-10-04 01:33:09
【问题描述】:

美好的一天。

我必须解析一些算术运算,例如:

A + b * 0.75 + 3

(c-Ff)-1/2

我需要将单独的元素分组。

所以我需要解析

let var1 = 'A';
let operator1 = '+';
let var2 = 'b';
let operator2 = '*';
let var3 = 0.75;
let operator3 = '+';
let var4 = 3;

所以我可以将我的 A 变量与我的预定义变量匹配并进行一些计算。

我以[^+/*()-]+ 结束,但它

  1. 捕获空格
  2. 不将 +-/* 放在不同的组中
  3. 我不知道如何处理括号

有什么建议吗?

【问题讨论】:

标签: javascript regex reactjs


【解决方案1】:

好的,以下是解析示例表达式的两种尝试:

function parseStringA(str) {
  var vars = []; // numerical constants, symbolic names
  var ops = [];  // mathematical operators
  str
  .replace(/([\+\-\*\/\(\)])/g, ' $1 ') // force spaces arount ops
  .split(/ +/)      // split on spaces
  .filter(Boolean)  // remove empty items
  .forEach(function(item) {
    if(item.match(/[\+\-\*\/\(\)]/)) {
      ops.push(item);
    } else {
      vars.push(item);
    }
  });
  return {
    vars: vars,
    ops: ops
  }
}

function parseStringB(str) {
  var expr = []; // { val, op }
  str
  .replace(/([\+\-\*\/\(\)])/g, ' $1 ') // force spaces arount ops
  .split(/ +/)      // split on spaces
  .filter(Boolean)  // remove empty items
  .forEach(function(item) {
    if(item.match(/[\+\-\*\/\(\)]/)) {
      expr.push({ val: '', op: item});
    } else {
      expr.push({ val: item, op: ''});
    }
  });
  return expr;
}


var str1 = 'A + b * 0.75 + 3';
var str2 = '(c-Ff)-1/2';

var result1a = parseStringA(str1);
console.log('result1a: ' + JSON.stringify(result1a, null, ' '))

var result2a = parseStringA(str2);
console.log('result2a: ' + JSON.stringify(result2a, null, ' '))

var result1b = parseStringB(str1);
console.log('result1b: ' + JSON.stringify(result1b, null, ' '))

var result1b = parseStringB(str2);
console.log('result1b: ' + JSON.stringify(result1b, null, ' '))

函数parseStringA() 将表达式拆分为(数字常量/符号名称)和数学运算符,根据您的原始示例。结果没有用,因为您丢失了表达式中的项目序列,从输出中可以看出:

result1a: {
 "vars": [
  "A",
  "b",
  "0.75",
  "3"
 ],
 "ops": [
  "+",
  "*",
  "+"
 ]
}
result2a: {
 "vars": [
  "c",
  "Ff",
  "1",
  "2"
 ],
 "ops": [
  "(",
  "-",
  ")",
  "-",
  "/"
 ]
}

更好的方法是函数parseStringB(),它返回一个包含val(数字常量/符号名称)和op(数学运算符)的对象数组。这是输出:

result1b: [
 { "val": "A",    "op": ""  },
 { "val": "",     "op": "+" },
 { "val": "b",    "op": ""  },
 { "val": "",     "op": "*" },
 { "val": "0.75", "op": ""  },
 { "val": "",     "op": "+" },
 { "val": "3",    "op": ""  }
]
result1b: [
 { "val": "",   "op": "(" },
 { "val": "c",  "op": ""  },
 { "val": "",   "op": "-" },
 { "val": "Ff", "op": ""  },
 { "val": "",   "op": ")" },
 { "val": "",   "op": "-" },
 { "val": "1",  "op": ""  },
 { "val": "",   "op": "/" },
 { "val": "2",  "op": ""  }
]

这种格式更有用。现在您可以遍历数组来解析表达式,这似乎超出了您的问题范围。

这是评估表达式的第一步,称为标记化 - 数组包含标记。下一步是创建一个解析树,以便您可以正确地从内到外评估括号、加法之前的乘法等。

这个博客有一个很好的概述:https://blog.bitsrc.io/parsing-expressions-in-javascript-4c156f0cbaec

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 2013-06-03
    • 2014-02-06
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 2018-04-09
    相关资源
    最近更新 更多