我正在使用正则表达式处理数学表达式解析器,我正在尝试添加对括号的支持。
我的解析器的工作方式如下:
function parse_expression(expression){
Find parenthetical expressions
Loop through parenthetical expressions, call parse_expression() on all of them
Replace parenthetical expression with value of expression
Find value of expression
Return value
}
因为它是递归的,我只需找到最外面的括号表达式。例如,如果我正在解析字符串“(5 +(4 +(3/4)+(3 * 2)+ 2))+(1 + 2)”,我想找到表达式“5 +(4 + (3/4)+(3 * 2)+ 2)“和”1 + 2“。你如何用正则表达式做到这一点?
我现在的正则表达式(“\(([^ \]] +)\)”)只返回“5 +(4 +(3 * 2”,它没有得到完整的第一个表达式,它没有得到第二个。
有什么想法吗?
谢谢,
凯尔
答案 0 :(得分:6)
不幸的是,任意嵌套括号的语言不规则,因此无法使用正则表达式进行匹配。
具体而言,常规语言是可以使用有限自动机解析的语言,其具有(设定)有限数量的状态。要匹配任意嵌套的括号集,需要任意数量的状态,以便在它们经过时计算括号。
大多数“正则表达式”库(尤其是perl)与常规语言并不严格匹配,但它们仍有此限制。
解决问题最直接的方法是递归下降解析器。一种效率低下的方法是只查看字符串,随时计算括号,找出要下降的子字符串。
如果你坚持操作是括号的,你也会发现你的解析器更简单,例如只允许(1 + 2)+3或1+(2 + 3)而不是1 + 2 + 3。
答案 1 :(得分:5)
既然你正在迭代这一切,我会说你仍然应该这样做,但是反过来。找到最小的paranthetical表达式子集,而不是最大的子集:
(\([^(]+\))
评估它们,并用它们的值替换它们,即第一次,匹配将是(3 / 4)
,(3 * 2)
和(1 + 2)
。分别用0,75
,6
和3
替换它们,给出一个新字符串:
(5 + (4 + 0,75 + 6 + 2)) + 3
然后你迭代它,直到没有更多的括号表达式,自下而上而不是自上而下(就像你手动解决这样的任务一样!)
除此之外,我同意所有其他人正是你要求的不应该(正确地 不能)使用正则表达式。但是你的问题可以通过这个涉及正则表达式的解决方案来解决。
答案 2 :(得分:2)
如果我没弄错的话,这种语言并不常见,因此用正则表达式来理解这种语言是不可能的。
答案 3 :(得分:2)
您应该使用解析器。让解析器遍历字符串,并在每次遇到a时递增括号计数(并在每次命中时递减计数)。当它接下来达到零计数时,你有最外面的括号表达式的范围。