问题描述
任何人都可以向我建议任何可以将乳胶数学转换为正常表达式 (x^2+2x+sin(x)) 的方法或库。 到目前为止,我已经找到了一个可以做到的代码,但它不能将 \sqrt[3]{....} 转换为 cuberoot(....) 或 root(3,....)
代码:
function MQtoAM(tex,display) {
var nested,lb,rb,isfuncleft,curpos,c,i;
tex = tex.replace(/\\:/g,' ');
tex = tex.replace(/\\operatorname{(\w+)}/g,' $1');
if (!display) {
while ((i = tex.lastIndexOf('\\left|'))!=-1) { //found a left |)
rb = tex.indexOf('\\right|',i+1);
if (rb!=-1) { //have a right | - replace with abs( )
isfuncleft = tex.substring(0,i).match(/(arcsinh|arccosh|arctanh|arcsech|arccsch|arccoth|arcsin|arccos|arctan|arcsec|arccsc|arccot|sinh|cosh|tanh|sech|csch|coth|ln|log|exp|sin|cos|tan|sec|csc|cot)(\^\d+)?$/);
tex = tex.substring(0,rb) + ")" + (isfuncleft?')':'') + tex.substring(rb+7);
tex = tex.substring(0,i) + (isfuncleft?'(':'') + "abs(" + tex.substring(i+6);
} else {
tex = tex.substring(0,i) + "|" + tex.substring(i+6);
}
}
tex = tex.replace(/\\text{\s*or\s*}/g,' or ');
tex = tex.replace(/\\text{all\s+real\s+numbers}/g,'all real numbers');
tex = tex.replace(/\\text{DNE}/g,'DNE');
tex = tex.replace(/\\varnothing/g,'DNE');
tex = tex.replace(/\\Re/g,'all real numbers');
} else {
tex = tex.replace(/\\Re/g,'RR');
}
tex = tex.replace(/\\begin{.?matrix}(.*?)\\end{.?matrix}/g,function(m,p) {
return '[(' + p.replace(/\\\\/g,'),(').replace(/&/g,',') + ')]';
});
tex = tex.replace(/\\le(?=(\b|\d))/g,'<=');
tex = tex.replace(/\\ge(?=(\b|\d))/g,'>=');
tex = tex.replace(/\\ne(?=(\b|\d))/g,'!=');
tex = tex.replace(/\\pm/g,'+-');
tex = tex.replace(/\\approx/g,'~~');
tex = tex.replace(/(\\arrow|\\rightarrow)/g,'rarr');
tex = tex.replace(/\\cup/g,'U');
tex = tex.replace(/\\times/g,'xx');
tex = tex.replace(/\\left\\{/g,'lbrace').replace(/\\right\\}/g,'rbrace');
tex = tex.replace(/\\left/g,'');
tex = tex.replace(/\\right/g,'');
tex = tex.replace(/\\langle/g,'<<');
tex = tex.replace(/\\rangle/g,'>>');
tex = tex.replace(/\\cdot/g,'*');
tex = tex.replace(/\\infty/g,'oo');
tex = tex.replace(/\\nthroot/g,'root');
tex = tex.replace(/\\mid/g,'|');
tex = tex.replace(/\\/g,'');
tex = tex.replace(/sqrt\[(.*?)\]/g,'root($1)');
tex = tex.replace(/(\d)frac/g,'$1 frac');
while ((i=tex.indexOf('frac{'))!=-1) { //found a fraction start
nested = 1;
curpos = i+5;
while (nested>0 && curpos<tex.length-1) {
curpos++;
c = tex.charat(curpos);
if (c=='{') { nested++;}
else if (c=='}') {nested--;}
}
if (nested==0) {
tex = tex.substring(0,i)+"("+tex.substring(i+5,curpos)+")/"+tex.substring(curpos+1);
} else {
tex = tex.substring(0,i) + tex.substring(i+4);
}
}
//separate un-braced subscripts using latex rules
tex = tex.replace(/_(\w)(\w)/g,'_$1 $2');
tex = tex.replace(/(\^|_)([+\-])([^\^])/g,'$1$2 $3');
tex = tex.replace(/\^(\w)(\w)/g,'^$1 $2');
tex = tex.replace(/_{([\d\.]+)}\^/g,'_$1^');
tex = tex.replace(/_{([\d\.]+)}([^\^])/g,'_$1 $2');
tex = tex.replace(/_{([\d\.]+)}$/g,'_$1');
tex = tex.replace(/_{(\w+)}$/g,'_($1)');
tex = tex.replace(/{/g,'(').replace(/}/g,')');
tex = tex.replace(/lbrace/g,'{').replace(/rbrace/g,'}');
tex = tex.replace(/\(([\d\.]+)\)\/\(([\d\.]+)\)/g,'$1/$2'); //change (2)/(3) to 2/3
tex = tex.replace(/\/\(([\d\.]+)\)/g,'/$1'); //change /(3) to /3
tex = tex.replace(/\(([\d\.]+)\)\//g,'$1/'); //change (3)/ to 3/
tex = tex.replace(/\/\(([\a-zA-Z])\)/g,'/$1'); //change /(x) to /x
tex = tex.replace(/\(([\a-zA-Z])\)\//g,'$1/'); //change (x)/ to x/
tex = tex.replace(/\^\(-1\)/g,'^-1');
tex = tex.replace(/\^\((-?[\d\.]+)\)/g,'^$1');
tex = tex.replace(/\/\(([\a-zA-Z])\^([\d\.]+)\)/g,'/$1^$2'); //change /(x^n) to /x^n
tex = tex.replace(/\(([\a-zA-Z])\^([\d\.]+)\)\//g,'$1^$2/'); //change (x^n)/ to x^n/
tex = tex.replace(/\+\-/g,'+ -'); // ensure spacing so it doesn't interpret as +-
tex = tex.replace(/text\(([^)]*)\)/g,'$1');
return tex;
}
解决方法
我会针对这种特定情况提供解决方案,但这并不总是可行的,因为 LaTeX 不保证数学表达式有效1。 LaTeX 也是一种 Turing Complete 编程语言,所以总有人可以写出一个你无法转换的方程。
在这种特殊情况下,您需要替换该行:
tex = tex.replace(/sqrt\[(.*?)\]/g,'root($1)');
与
tex = tex.replace(/sqrt\[(.*?)\]\{(.*?)\}/g,'root($1,$2)');
右侧的“$number”部分表示“从左侧复制第 number 个括号中的内容”。在这里,我只是告诉它在方括号/大括号中查找内容并采取相应的行动。这种搜索和替换方式称为regular expression parsing。我建议您学习自己编写代码,这样您就可以增加解析器理解的内容。
例如,您可以添加一行:
tex = tex.replace(/sqrt\{(.*?)\}/g,'squareroot($1)');
处理简单的平方根。
遗憾的是,每种语言都以不同的方式实现正则表达式(尤其是在它们前面需要一个“\”的东西),因此您必须进行一些试验才能找到在 JavaScript 中有效的方法。
1 这就是为什么在撰写文章时最好将公式自动转换为 LaTeX 而不是直接在 LaTeX 中编写它们的最佳做法的一个很好的原因。发现已发表的数学无效的论文是非常常见的,因为人们直接用 LaTeX 编写,然后错误是不可见的,因为在原始 LaTeX 源中发现错误是多么困难。