微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

正则表达式 – 使用正则表达式匹配数学表达式?

例如,这些是有效的数学表达式:
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)

原文地址:https://www.jb51.cc/regex/357406.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐