例如,这些是有效的数学表达式:
a * b + c -a * (b / 1.50) (apple + (-0.5)) * (boy - 1)
这些是无效的数学表达式:
--a *+ b @ 1.5.0 // two consecutive signs,two consecutive operators,invalid operator,invalid number -a * b + 1) // unmatched parentheses a) * (b + c) / (d // unmatched parentheses
我没有匹配浮点数的问题,但是与括号匹配有困难。任何想法?如果比正则表达式更好的解决方案,我也会接受。但是正则表达式是首选的。
========
编辑:
我想对我选择的“接受答案”作出一些评论,希望有相同问题的人发现这个话题不会被误导。
有几个答案我认为“接受”,但我不知道哪一个是最好的。所以我选择了接受的答案(几乎)随机。我建议阅读纪尧姆Malartre的答案以及除了接受的答案。所有这些都为我的问题提供了实际的解决方案。对于一个有些严格/理论的答案,请阅读David Thornley在接受答复的意见。正如他所说,Perl对正则表达式的扩展(源自常规语言)使其“不规则”。 (我在我的问题中没有提到任何语言,所以大多数答复者都假设Perl实现了正则表达式 – 可能是最受欢迎的实现,当我发布了我的问题时,我也是这样)
如果我上面说错了,请更正我。
匹配括号与正则表达式是很有可能的。
这是一个Perl脚本,将解析任意深度匹配的括号。虽然它会抛出外面的不匹配的括号,但我没有专门设计来验证括号。只要平衡,它将解析任意深的括号。这将让你开始。
关键是在正则表达式和使用它的递归。玩它,我相信你可以得到这个也标志不匹配的prens。我想如果你捕获这个正则表达式抛出并计数括号(即在非匹配文本中测试奇数括号),那么你有无效的不平衡括号。
#!/usr/bin/perl $re = qr / ( # start capture buffer 1 \( # match an opening paren ( # capture buffer 2 (?: # match one of: (?> # don't backtrack over the inside of this group [^()]+ # one or more ) # end non backtracking group | # ... or ... (?1) # recurse to opening 1 and try it again )* # 0 or more times. ) # end of buffer 2 \) # match a closing paren ) # end capture buffer one /x; sub strip { my ($str) = @_; while ($str=~/$re/g) { $match=$1; $striped=$2; print "$match\n"; strip($striped) if $striped=~/\(/; return $striped; } } while(<DATA>) { print "start pattern: $_"; while (/$re/g) { strip($1) ; } } __DATA__ "(apple + (-0.5)) * (boy - 1)" "((((one)two)three)four)x(one(two(three(four))))" "a) * (b + c) / (d" "-a * (b / 1.50)"
输出:
start pattern: "(apple + (-0.5)) * (boy - 1)" (apple + (-0.5)) (-0.5) (boy - 1) start pattern: "((((one)two)three)four)x(one(two(three(four))))" ((((one)two)three)four) (((one)two)three) ((one)two) (one) (one(two(three(four)))) (two(three(four))) (three(four)) (four) start pattern: "a) * (b + c) / (d" (b + c) start pattern: "-a * (b / 1.50)" (b / 1.50)