好的,以下是解析示例表达式的两种尝试:
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