一个算术表达式可能含有以下元素:
数字,运算符(+-*/),正号负号,小括号。
求其正则表达式。。

解决方案 »

  1.   

    Regex regex = new Regex(@"
    ^                       (?#匹配开头)
    [-+]?                   (?#开头可以出现正负号)
    ([0-9]+($|[-+*/]))*     (?#可选数-符号-数-符号-……-数-符号或结尾)
    (
        (
            (?<o>\()        (?#左括号,保存到o名字下)
            [-+]?           (?#可选正负号)
            ([0-9]+[-+*/])* (?#可选数-符-数-符……)
        )+                  (?#可以重复出现左括号)
        [0-9]+              (?#左右括号之间最起码需要一个操作数)
        (                   (?#)
            (?<-o>\))       (?#右括号,匹配的同时去掉一个左括号)
            ([-+*/][0-9]+)* (?#可选符-数-符-数……)
        )+                  (?#可以重复出现右括号,仅当还有左括号剩余)
        ($|[-+*/])          (?#要么结尾,要么在下一个左括号出现之前出现一个运算符)
    )*                      (?#重复出现左括号)
    (?(o)(?!))              (?#如果还有左括号剩余就不匹配任何东西)
    $                       (?#匹配结尾)
    ", RegexOptions.IgnorePatternWhitespace);
                string[] tests = new string[] {
                    "1",
                    "1+23",
                    "1+23*456",
                    "1*(23+456)",
                    "(3)",
                    "((67+8)*9+10)/11",
                    "12+(13*)",
                    "(()",
                    "((3)",
                    "(3))",
                    "+3",
                    "5*(4+3/(-2))",
                    "(5*(4+3/(-2))",
                    "5*(4+3/(-2)))",
                };
                foreach (string s in tests)
                    Console.WriteLine("{0}: {1}", regex.IsMatch(s) ? "Good" : " Bad", s);
                Console.ReadKey();
                //结果:
                //Good: 1
                //Good: 1+23
                //Good: 1+23*456
                //Good: 1*(23+456)
                //Good: (3)
                //Good: ((67+8)*9+10)/11
                // Bad: 12+(13*)
                // Bad: (()
                // Bad: ((3)
                // Bad: (3))
                //Good: +3
                //Good: 5*(4+3/(-2))
                // Bad: (5*(4+3/(-2))
                // Bad: 5*(4+3/(-2)))我猜只有.NET的RegEx提供“平衡组定义匹配”(Balanced group definition)参考:http://blogs.msdn.com/bclteam/archive/2005/03/15/396452.aspx
      

  2.   

    需要修正一下……结尾之前加了个判断            Regex regex = new Regex(@"
    ^                               (?#匹配开头)
    [-+]?                           (?#开头可以出现正负号)
    ([0-9]+($|[-+*/]))*             (?#可选数-符号-数-符号-……-数-符号或结尾)
    (
        (
            (?<o>\()                (?#左括号,保存到o名字下)
            [-+]?                   (?#可选正负号)
            ([0-9]+[-+*/])*         (?#可选数-符-数-符……)
        )+                          (?#可以重复出现左括号)
        [0-9]+                      (?#左右括号之间最起码需要一个操作数)
        (
            (?<-o>\))               (?#右括号,匹配的同时去掉一个左括号)
            ([-+*/][0-9]+)*         (?#可选符-数-符-数……)
        )+                          (?#可以重复出现右括号,仅当还有左括号剩余)
        ($|[-+*/])                  (?#要么结尾,要么在下一个左括号出现之前出现一个运算符)
    )*                              (?#重复出现左括号)
    (?(o)(?!))                      (?#如果还有左括号剩余就不匹配任何东西)
    (?<=[0-9)])                     (?#检查结尾前是否数字或右括号)
    $                               (?#匹配结尾)
    ", RegexOptions.IgnorePatternWhitespace);
                string[] tests = new string[] {
                    "1",
                    "1+23",
                    "1+23*456",
                    "1*(23+456)",
                    "(3)",
                    "((67+8)*9+10)/11",
                    "12+(13*)",
                    "()",
                    "((3)",
                    "(3))",
                    "+3",
                    "5*(4+3/(-2))",
                    "(5*(4+3/(-2))",
                    "5*(4+3/(-2)))",
                    "+3*",
                    "+(4)+(-5)",
                    "+(4)(5)",
                };
                foreach (string s in tests)
                    Console.WriteLine("{0}: {1}", regex.IsMatch(s) ? "Good" : " Bad", s);
                Console.ReadKey();
      

  3.   

    TO: netmicro(麦) 。。不错,我要的正是这样的结果。。
    关键是我没想到这一步:(?<o>\()(?#左括号,保存到o名字下)
    因此自己没能写出来。。好。。散分了。。