目前正在做的一个项目遇到一个比较头痛的问题,HTML中有可以相当好的表示文字上标与下标。但是,在输入框中录入却非常不方便。如果由录入者输入"^"来代表上标,"_"来代表下标,"("和")"来分离不同的部分,应该可以大大加快录入速度。录入时如果这样输入:x^3^2,或者(Fe_2)(O_3),是不是简单多了。
于是,我用Javascript做了一个解析器,实现这类表达式的基本解释功能。
function translateExpression(expression){//HTML上下标表示式解析
this.expression=expression;
this.isPair=0;//括号是否配对
this.result='';
}
translateExpression.prototype={
upMark:'^',//上标
downMark:'_',//下标
s:[],//堆栈stack
isCheck:false,//是否是检查公式正确性
init:function(isCheck){
this.isCheck=isCheck||false;
this.s=[''];//初始化为'',防止溢出
if(0==this.expression.length){//如果是空串,则返回
this.result=this.expression;
return this.returnResult();
}
var exp=this.expression.split('');
var l=exp.length,mark;
for(var i=0;i<l;i++){
if(this.isPair<0) this.exception();//防止表达式右括号多于左括号
switch(exp[i]){
case this.upMark:
case this.downMark:
mark=(exp[i]==this.upMark)?'sup':'sub';
this.result+='<'+mark+'>';
this.s.push('</'+mark+'>');
break;
case this.leftBracket:
this.isPair++;
this.s.push('');
break;
case this.rightBracket:
this.isPair--;
this.writeClose();
break;
default:
this.result+=exp[i];
}
}
if(0!=this.isPair) this.exception();//括号不配对
this.pushAllData();
return this.returnResult();
},
exception:function(){
if(this.isCheck) return false;
return this.expression;
},
pushAllData:function(){//把留在堆栈里的数据释放出来
while(this.s.length>1)
this.result+=this.s.pop();
},
writeClose:function(){
var tmp;
do{
tmp=this.s.pop();
this.result+=tmp;
}while(tmp!='');
},
returnResult:function(){
if(this.isCheck) return true;
return this.result;
}
};
function parseSub(subStr){//调用函数
return (new translateExpression(subStr)).init();
}
用法:调用函数parseSub(表达式);返回解析后的HTML。如果表达式有错,则返回未解析的表达式。
测试:
var e='mp+(20^(1.0_(n^4+(2_5)-(3^(8_(3^9)))+6-4-3)+9))-78+(12^3)*20';
程序还有很多需要改进的地方,本文只是提供一种思路,抛砖引玉,请大家一起来讨论讨论。
我很喜欢javascript这种编程语言,如有同行中高手能够共同进步,则幸甚。