将括号表达式与正则表达式匹配

时间:2009-12-22 09:36:39

标签: objective-c regex math

我正在使用正则表达式处理数学表达式解析器,我正在尝试添加对括号的支持。

我的解析器的工作方式如下:

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”,它没有得到完整的第一个表达式,它没有得到第二个。

有什么想法吗?

谢谢,

凯尔

4 个答案:

答案 0 :(得分:6)

不幸的是,任意嵌套括号的语言不规则,因此无法使用正则表达式进行匹配。

具体而言,常规语言是可以使用有限自动机解析的语言,其具有(设定)有限数量的状态。要匹配任意嵌套的括号集,需要任意数量的状态,以便在它们经过时计算括号。

大多数“正则表达式”库(尤其是perl)与常规语言并不严格匹配,但它们仍有此限制。

解决问题最直接的方法是递归下降解析器。一种效率低下的方法是只查看字符串,随时计算括号,找出要下降的子字符串。

如果你坚持操作是括号的,你也会发现你的解析器更简单,例如只允许(1 + 2)+3或1+(2 + 3)而不是1 + 2 + 3。

答案 1 :(得分:5)

既然你正在迭代这一切,我会说你仍然应该这样做,但是反过来。找到最小的paranthetical表达式子集,而不是最大的子集:

(\([^(]+\))

评估它们,并用它们的值替换它们,即第一次,匹配将是(3 / 4)(3 * 2)(1 + 2)。分别用0,7563替换它们,给出一个新字符串:

(5 + (4 + 0,75 + 6 + 2)) + 3

然后你迭代它,直到没有更多的括号表达式,自下而上而不是自上而下(就像你手动解决这样的任务一样!)

除此之外,我同意所有其他人正是你要求的不应该(正确地 不能)使用正则表达式。但是你的问题可以通过这个涉及正则表达式的解决方案来解决。

答案 2 :(得分:2)

如果我没弄错的话,这种语言并不常见,因此用正则表达式来理解这种语言是不可能的。

答案 3 :(得分:2)

您应该使用解析器。让解析器遍历字符串,并在每次遇到a时递增括号计数(并在每次命中时递减计数)。当它接下来达到零计数时,你有最外面的括号表达式的范围。