所以我正在编写自己的餐巾纸数学解析器[1]来娱乐。餐巾数学是我正在构建的自定义文本编辑器的一部分 - 当您在等号后按空格时,它会检测等号之前的方程式并为您进行数学计算。例如,您输入 1+1=
,它会神奇地为您踢出 2
,这样屏幕上就会出现 1+1=2
。
我真的很难让正则表达式在等号之前匹配方程式。我的大脑被击中了,我迫切需要正则表达式之王的帮助。下面是我的测试字符串,突出显示的部分是我希望正则表达式匹配的部分。
特别是,我无法让正则表达式匹配方程的真实开头。如果等式开始之前有数字或单词,我当前的正则表达式就会被抛出。我觉得我需要以某种方式从等号开始向后工作。我开始反转我的字符串字符,就在那时我举起双手来向你寻求帮助。
我的测试字符串与所需的匹配
(字符串的真实方程部分):
测试文本 (1) pi
=
测试文本 (1 pi
=
测试文本1) pi
=
测试文本 (2) pi + 10/20
=
测试文本 (3) 测试 pi ^ 10/20
=
测试文本 (30) 10 + 5
=
测试文本 (500) abs(10 + 5)
=
测试文本 (1) pi + 10/20
=
测试文本10*5
=
测试文本pi/phi
=
测试文本10 mod phi
=
测试文本 50 10 mod phi
=
测试文本pi mod abs(phi)
=
苹果香蕉樱桃苹果 10 苹果樱桃香蕉喜 10 99+1
=
以下是餐巾纸数学中允许且有用的所有特殊关键字:
var napkinMathKeyWords = [
'pi',
'\\u03C0',
'\\u03A0',
'phi',
'\\u03C6',
'\\u03A6',
'abs',
'acos',
'cos',
'atan',
'tan',
'asin',
'sin',
'ceil',
'floor',
'sqrt',
'log',
'ln',
'mod',
];
编辑
这是我到目前为止得到的正则表达式:
(\d|pi|\\u03C0|\\u03A0|phi|\\u03C6|\\u03A6|abs|acos|cos|atan|tan|asin|sin|ceil|floor|sqrt|log|ln|mod).*?=
它满足了我的大部分情况,只有少数情况下它会失败:
[1] http://blogs.msdn.com/b/onenotetips/archive/2008/05/09/napkin-math-in-onenote.aspx
最佳答案
正如您所暗示的,这个正则表达式有点困惑。但我有一个有效的(请参阅 regex101 )。在 regex101 上,我使用了 PCRE 模式,但只是这样我可以使用“扩展”选项来使正则表达式更具可读性。在 JavaScript 中,只需折叠所有换行符和空格即可。
我发现您的关键字列表包含两个不同的组:
关键字是函数,后面跟括号中的运算
var regex_function = "(abs|acos|cos|atan|tan|asin|sin|ceil|floor|sqrt|log|ln)\([^)]+
)";常量关键字(独立)
var regex_constant = "(\d+|pi|\\u03C0|\\u03A0|phi|\\u03C6|\\u03A6)";
那么以上部分的组合(交替)就代表一个操作数:
var regex_operand = "("+ regex_constant + "|"+ regex_function + ")";
每个操作数之间必须有一个运算符:
var regex_operator = "([+\-*\/^]|mod)";
整个正则表达式可以像这样组合在一起:
var regex = new RegExp(regex_operand + "(\s*"+ regex_operator + "\s*"+ regex_operand + ")*\s*=");
基本上,您有一个操作数,后跟任意数量的运算符/操作数对,然后是等号。
关于javascript - 我的餐巾纸数学解析器上复杂正则表达式的逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26914652/