使用 javascript 中的数学方程拆分变量
Posted
技术标签:
【中文标题】使用 javascript 中的数学方程拆分变量【英文标题】:Split a variable using mathematical equations in javascript 【发布时间】:2015-11-23 06:29:39 【问题描述】:其实我有两个问题。
我要做的是首先检查用户输入的值是否是正确的数学方程。例如,如果用户输入x + y ( z
,这应该检测为无效公式,x + y ( z )
为正确公式,
我要做的第二件事是将公式与+ - * / ()
符号分开,所以上面的公式将返回为x, y, z
。
我所做的如下
var arr = [];
var s = 'x + y ( z )';
arr = s.split("(?<=[-+*/])|(?=[-+*/])");
console.log(arr);
这会返回一个数组,其中只有一个数据,例如 [x + y ( z )]
另外,变量不是单个字母。他们可能是 年价、收盘价等词
谁能帮我解决这个问题。提前致谢
更新:我也试过"/[^+/*()-]+/g"
【问题讨论】:
javascript 中没有lookbehind @anubhava 我也试过 /[^+/*()-]+/g,没用 为什么不首先根据一些规则验证它是否是一个有效的数学表达式,然后解析出其中的所有字母? P.S.将您的问题分成两个不同的帖子可以更有效地获得答案。 【参考方案1】:第二部分:
var s = 'x + y ( z )';
var arr = s.match(/(\w)/g);
console.log(arr);
document.write(JSON.stringify(arr));
当然,你要先检查输入的有效性。
编辑:使用 Tomer W 的回答建议 eval()
:
function checkExpression(str)
// check for allowed characters only
if (/[^\w\d\(\)\+\*\/\-\s]/.exec(s) != null)
return false;
// extract variable names, assuming they're all one letter only
var arr = s.match(/(\w+)/g);
// instantiate the variables
arr.forEach(function (variable)
eval(variable + '= 1');
);
// ( is alone, replace it by * (
str = str.replace(/\(/g, '* (');
try
eval(str);
return true;
catch (ex)
console.log(ex);
return false;
它很脏,但大部分时间都有效(Tomer W 指出了一些边缘情况,例如 ++62+5
或 54++++6
可以通过另一个正则表达式检查来避免),你有更复杂的例子要测试吗?
【讨论】:
上面的表达式也会将 arr 从 % 符号中拆分出来,我想要的只是从 / * - + ( ) 拆分出来 是的,您必须先检查有效性。这里的“惰性”解决方案是生成解析器,此处给出的示例正是您想要的,但生成的代码是 18Ko:pegjs.org/online 我无法使用解析器,因为公式中的变量没有有效值。它只是变量。我只是想确保它是一个有效的公式 其实是的。由于公式是用户输入的,它可以是任何东西。这就是我要检查公式有效性的原因。用户可以输入公式,例如 x*2+y(4 . 不正确。缺失 )。我应该验证这种公式并给出错误 另一件事,变量不是单个字母。它们可以是诸如年价、收盘价等词【参考方案2】:警告词
非常非常非常危险的方法!!!
我发布这个是因为它是一个有效的答案,但你应该非常小心地这样做,因为用户可能会完全搞砸你的网站。不要让一个用户输入用于 eval给另一个用户!!!永远!!!
实际答案
可以使用浏览器自带的java-script编译器,使用eval()
function checkEq(equ)
for(ch in equ)
// check that all characters in input are "equasion usable"
if(" +-*/1234567890e^&%!=".indexOf(ch) === -1)
// if there are invalid chars
return false;
try
// try running the equ, will throw an exception on a syntax error.
eval(equ);
return true; // no exception
catch(ex)
return false; // syntax error
Plunker example
正如我之前提到的!非常小心!
【讨论】:
我尝试消除eval
中大多数字符的使用,但一个漂亮的黑客可能能够使用&###;
制作一些艺术作品(尽管他没有;
)
除了输入中填充了变量名,所以它总是会失败(到处都是引用错误),但是使用我的答案来获取变量名,然后在使用你的 eval 之前创建它们可以工作。这是危险的聪明:D
你也可以允许变量为x
y
z
,但这会让用户写出my_nasty_function();
这样的东西:)
发现另一个需要注意的问题 :) 因为54+++6
是有效的并导致60
,同样++62+5
导致68
:)
我用你的输入更新了我的答案,使用 eval()
很脏,但它对这么少的行效果很好(只要输入是安全的)。不过,我仍然会使用真正的解析器来涵盖所有情况。【参考方案3】:
使用@ShanShan 和@Tomer W 的答案,我编写了一个公式验证器。代码如下。在这个验证器中,我检查左括号和右括号、额外的 / * - + 符号、不需要的符号等。
如果用户想要使用 x,y,z 创建和验证公式 变量,用户必须将变量添加到数组并将其传递给 这个验证器写了公式,所以验证器接受 不是数字的变量。
我还使用了这篇文章中提到的自定义集。 https://***.com/a/4344227/918277
重要提示:此 java 脚本函数无法验证包含 sin、cos、tan、log 等的非常复杂的公式。脚本会将它们识别为字母并返回 false。
function StringSet()
var setObj = , val = ;
this.add = function(str)
setObj[str] = val;
;
this.contains = function(str)
return setObj[str] === val;
;
this.remove = function(str)
delete setObj[str];
;
this.values = function()
var values = [];
for ( var i in setObj)
if (setObj[i] === val)
values.push(i);
return values;
;
/**
*
* @param _formulaInputs
* Array of use entered inputs to be use in formula
* @param _formula
* User entered formula
* @returns Boolean
*/
function validateFormula(_formulaInputs, _formula)
var formula = _formula;
var bracketStack = new Array();
var formulaDescArray = [];
var formulaDescInForm = new StringSet();
for (var i = 0; i < _formulaInputs.length; i++)
formulaDescInForm.add(_formulaInputs[i]);
/* Regex to check for unwanted symbols(! @ # $ etc.) */
if (/[^\w\d\(\)\+\*\/\-\s]/.exec(formula) != null)
return false;
for (var i = 0; i < _formula.length; i++)
if ((_formula.charAt(i) == '/' || _formula.charAt(i) == '*'
|| _formula.charAt(i) == '-' || _formula.charAt(i) == '+')
&& (_formula.charAt(i + 1) == '/'
|| _formula.charAt(i + 1) == '*'
|| _formula.charAt(i + 1) == '-' || _formula
.charAt(i + 1) == '+'))
return false;
var lastChar = formula.charAt(formula.length - 1);
if (lastChar == '/' || lastChar == '*' || lastChar == '-'
|| lastChar == '+')
return false;
formulaDescArray = formula.split(/[\/\*\-\+\()]/g);
/* Remove unwanted "" */
for (var i = 0; i < formulaDescArray.length; i++)
if (formulaDescArray[i].trim().length == 0)
formulaDescArray.splice(i, 1);
i--;
/* Remove unwanted numbers */
for (var i = 0; i < formulaDescArray.length; i++)
if (!isNaN(formulaDescArray[i]))
formulaDescArray.splice(i, 1);
i--;
for (var i = 0; i < formulaDescArray.length; i++)
if (!formulaDescInForm.contains(formulaDescArray[i].trim()))
return false;
for (var i = 0; i < formula.length; i++)
if (formula.charAt(i) == '(')
bracketStack.push(formula.charAt(i));
else if (formula.charAt(i) == ')')
bracketStack.pop();
if (bracketStack.length != 0)
return false;
return true;
【讨论】:
以上是关于使用 javascript 中的数学方程拆分变量的主要内容,如果未能解决你的问题,请参考以下文章
组合数学经典方程的对偶方程一个不等式问题(例题:acwing1312 序列统计)
SOR迭代法实验报告c语言,数学实验“线性方程组的J-迭代,GS-迭代,SOR-迭代解法”实验报告(内含matlab程序代码).doc...