<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>suanshu</title>
<!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> -->
<script type="text/javascript">
var pattBrackets = /\([^\(\)]*\)/gm;
function main () {
var testStr = '1+4+(22+33)*((4+7)/6)+(3*4+(4+5))+100';
//console.log('source:',testStr)
var tempArrBrackes = [];
var temp3MArr = [];
var subArr = [];
var regExpShow = document.getElementById('regExp');
regExpShow.innerHTML = regExpShow.innerHTML + '<br>算式: ' +testStr;
//解析出 括号中的内容
while(subArr = testStr.match(pattBrackets)) {
for (var i = 0;i < subArr.length ; i++)
{
var name = getName();
tempArrBrackes.push({name:name, formula:subArr[i].substring(1,subArr[i].length - 1)});
testStr = testStr.replace(subArr[i], name);
}
}
tempArrBrackes.push({name:getName(), formula:testStr});
//把没有括号的 算式的 数组 解析成 a+b=n的树
for (var i = 0; i < tempArrBrackes.length ; i++)
{
var mArr = getStrByParrt(tempArrBrackes[i].formula, tempArrBrackes[i].name);
if (mArr)
{
temp3MArr = temp3MArr.concat(mArr);
}
}
//计算 并 将结果树打印到页面
var tree = getValue(temp3MArr);
for (var key in tree)
{
regExpShow.innerHTML = regExpShow.innerHTML + '<br>'+key+': ' + tree[key].formula + ' = ' +tree[key].value;
}
}
//解析最简单的 计算式 a + b = n
var pattArr = [/n{0,1}\d+\*{1}n{0,1}\d+/
,/n{0,1}\d+\/{1}n{0,1}\d+/
,/n{0,1}\d+\+{1}n{0,1}\d+/
,/n{0,1}\d+\-{1}n{0,1}\d+/];
var pattD = /[\+\-\*\/]/gm;
function getStrByParrt (iStr, iName) {
//console.log('----------------------------:',iStr);
var ret = [];
var subStr = [];
for (var i = 0; i < pattArr.length; i++)
{
while(subStr = iStr.match(pattArr[i])) {
if (iStr.match(pattD).length == 1)
{
ret.push({name:iName, formula:subStr[0]});
break;
}
var name = getName();
ret.push({name:name, formula:subStr[0]});
iStr = iStr.replace(subStr, name);
}
}
//console.log('pattD',ret.toString())
return ret;
}
// 计算式 算值
function getValue (m3Arr) {
var retTree = {};
for (var i = 0; i < m3Arr.length ; i++)
{
var formula = m3Arr[i].formula;
var name = m3Arr[i].name;
var sign = formula.match(pattD)[0];
var params = formula.split(sign);
retTree[name] = {
formula : formula
,value : ''
};
switch(sign){
case '+' : retTree[name].value = getValueFromTree(retTree, params[0]) + getValueFromTree(retTree, params[1]); break;
case '-' : retTree[name].value = getValueFromTree(retTree, params[0]) - getValueFromTree(retTree, params[1]); break;
case '*' : retTree[name].value = getValueFromTree(retTree, params[0]) * getValueFromTree(retTree, params[1]); break;
case '/' : retTree[name].value = getValueFromTree(retTree, params[0]) / getValueFromTree(retTree, params[1]); break;
}
}
return retTree;
}
// 字符串 转数字 变量不转
function getValueFromTree(tree, name) {
var value = '';
if (name.indexOf('n') >=0)
{
value = parseFloat(tree[name].value);
} else {
value = parseFloat(name);
}
return value;
}
//取变量名
var nameIndex = 0;
function getName () {
return 'n' + nameIndex++;
}
</script>
</head>
<body οnlοad=''>
<div id='show' style='height:30px'>'1+4+(22+33)*((4+7)/6)+(3*4+(4+5))+100'</div>
<input type='button' value='jisuan' οnclick='main()'>
<div id='regExp'></div>
</body>
</html>