有如下表达式字符串:
            string str1 = @"    if 条件1 : 
        if 子条件1 : 子结果1
        else 子条件2 : 子结果2
    elif 条件2 : 
                计算2
    elif 条件3 :     计算3
    elif 条件4 : 计算4    else :
            计算5";要点:
1.表达式规则一般有一下几种形式:
第一种:
if <条件>  : <结果>  _回车
(这里可能带几个换行)
elif <条件>  : <结果>  _回车
else  : <结果>
这种情况一般 <结果>是单个计算表达式,没有if else子逻辑运算表达式
第二种:
if <条件>  :    _回车
<结果>  _回车
elif <条件>  :  _回车
<结果>  _回车
else  :
<结果>
这种 <结果>一般是单个计算表达式或含有if else的子逻辑运算表达式
第三种:
混用的情况,如例子的顶层的if和最后的else。
2. <结果>内可能嵌套其他if else表达式,不过if else前肯定有缩进空格
3.从前缩进空格数可以看出是否同组的if else。
4.存在只有if没有elif或else的情况。
5.if elif else肯定都是小写。 需求:
将头尾多余空格和回车去掉,而且第一层的if elif else开头的前面空格都去掉,子层嵌套的可以不随主层次的一同缩进,也可以不缩进。预期结果:
            string str1 = @"if 条件1 : 
    if 子条件1 : 子结果1
    else 子条件2 : 子结果2
elif 条件2 : 
            计算2
elif 条件3 :     计算3
elif 条件4 : 计算4else :
        计算5";或            string str1 = @"if 条件1 : 
        if 子条件1 : 子结果1
        else 子条件2 : 子结果2
elif 条件2 : 
                计算2
elif 条件3 :     计算3
elif 条件4 : 计算4else :
            计算5;

解决方案 »

  1.   

    using System;
    using System.Text.RegularExpressions;class Program
    {
      static string str1 = @" 
        if 条件1 : 
            if 子条件1 : 子结果1 
            else 子条件2 : 子结果2 
        elif 条件2 : 
                    计算2 
        elif 条件3 :    计算3 
        elif 条件4 : 计算4     else : 
                计算5 ";   static void Main()
      {
        string s = RemoveEmptyLine(str1);
        s = RemoveStartSapces(s);
        Console.WriteLine("[{0}]", s);
      }
      
      // 去除空行
      static string RemoveEmptyLine(string s)
      {
        return Regex.Replace(s, @"(?m)^\s*$", "").Replace("\r\n\r\n", "\r\n").TrimStart('\r', '\n');
        // 如果也想去掉末尾的回车,只需所把 TrimStart 改成 Trim 即可。
      }  // 去除开头的空白
      static string RemoveStartSapces(string s)
      {
        string spaces = Regex.Match(s, @"^\s*").Value;
        return Regex.Replace(s, "(?m)^" + spaces, "");
      }
    }
      

  2.   

    using System;
    using System.Text.RegularExpressions;class Program
    {
      static string str1 = @" 
        if 条件1 : 
            if 子条件1 : 子结果1 
            else 子条件2 : 子结果2 
        elif 条件2 : 
                    计算2 
        elif 条件3 :    计算3 
        elif 条件4 : 计算4     else : 
                计算5 ";   static void Main()
      {
        string s = RemoveEmptyLine(str1);
        s = RemoveStartSapces(s);
        Console.WriteLine("[{0}]", s);
      }
      
      // 去除空行
      static string RemoveEmptyLine(string s)
      {
        return Regex.Replace(s, @"(?m)^\s*$", "").Replace("\n\n", "\n").TrimStart('\r', '\n');
        // 如果也想去掉末尾的回车,只需所把 TrimStart 改成 Trim 即可。
      }  // 去除开头的空白
      static string RemoveStartSapces(string s)
      {
        string spaces = Regex.Match(s, @"^\s*").Value;
        return Regex.Replace(s, "(?m)^" + spaces, "");
      }
    }/* 输出:
    [if 条件1 : 
        if 子条件1 : 子结果1 
        else 子条件2 : 子结果2 
    elif 条件2 : 
                计算2 
    elif 条件3 :    计算3 
    elif 条件4 : 计算4 
    else : 
            计算5 
    ]
    */
      

  3.   

    另外在贴子:
    http://topic.csdn.net/u/20090203/09/341714a1-2595-4564-a0af-0ced7b9bc8a5.html
    的末尾我加了个回复:在最后一小段前面加上是否实际捕获的判断 if (m.Groups["key3"].Success) 就可以了:       // 匹配到的 else 的 key3 及 value3
          if (m.Groups["key3"].Success)
          {
            string key3   = m.Groups["key3"  ].Value.Trim();
            string value3 = m.Groups["value3"].Value;
            Console.WriteLine("Key3   = [{0}]", key3  );
            Console.WriteLine("Value3 = [{0}]", value3);
          }
      

  4.   

    http://topic.csdn.net/u/20090104/14/730129c8-0843-4918-8c3d-8d99f8508888.html【求个小正则】密码至少要设8位数以上,其中至少要三个字母 我的解答是:"(?i)^(?=.*[A-Z].*[A-Z].*[A-Z]).{8,}$"
      

  5.   

    这个问题解决了,不过之前你给我解答的一个正则问题有性能问题。帮忙分析一下。不行的话只能用字符串解析了。
            [Test]
            public void RegTestIfElse1()
            {
                string str1 = @"
    if [当月考勤表.病假] > 0 :  if #连续工龄#<10 : #基薪标准#*0.5+(#基薪标准#*0.5*[当月考勤表.病假]/21.75) + #基薪标准#*([当月考勤表.事假]+[当月考勤表.旷工])/21.75
      elif #连续工龄#<20 and #连续工龄#>=10 : #基薪标准#*0.4+(#基薪标准#*0.4*[当月考勤表.病假]/21.75) + #基薪标准#*([当月考勤表.事假]+[当月考勤表.旷工])/21.75
      elif #连续工龄#<30 and #连续工龄#>=20 : #基薪标准#*0.3+(#基薪标准#*0.3*[当月考勤表.病假]/21.75) + #基薪标准#*([当月考勤表.事假]+[当月考勤表.旷工])/21.75
      elif #连续工龄#>=30 : #基薪标准#*0.2+(#基薪标准#*0.2*[当月考勤表.病假]/21.75) + #基薪标准#*([当月考勤表.事假]+[当月考勤表.旷工])/21.75
      else : 0
    elif 1==1: #基薪标准#*([当月考勤表.事假]+[当月考勤表.旷工])/21.75
    ";
                for (int i = 0; i < 6500 * 10; i++)
                {
                    ArrayList targetTable = GetLogicFormulaTopLevelIfThenList(str1);                Assert.AreEqual(2, targetTable.Count);
                }//这里要20多秒,循环次数接近但小于正式场景。
            }        private ArrayList GetLogicFormulaTopLevelIfThenList(string orginalFormulaScript)
            {
                ArrayList targetList = new ArrayList();            orginalFormulaScript = orginalFormulaScript.Trim().Replace("\r\n", "\n");
                string pattern = @"(?msix)
    ^(\s*)if\b(?<key1>.*?):(?<value1>.*?)    # 匹配 if 并记录前导空格
    (^\1elif\b(?<key2>.*?):(?<value2>.*?))*  # 匹配对应的 elif ,0个或多个
    (^\1else\b(?<key3>.*?):(?<value3>.*?))?  # 匹配对应的 else ,0个或1个
    \Z                                       # 匹配整个字符串末尾
    ";
                MatchCollection mc = Regex.Matches(orginalFormulaScript, pattern);
                foreach (Match m in mc)
                {
                    // 匹配到的第一个 if 的 key1 及 value1
                    KeyValuePair<string, string> kv1 = new KeyValuePair<string, string>(m.Groups["key1"].Value.Trim(), m.Groups["value1"].Value);
                    if (!kv1.Key.Equals(string.Empty) || !kv1.Value.Equals(string.Empty))
                    {
                        targetList.Add(kv1);
                    }                // 匹配到的 elif 的 key2 及 value2 (可能有多个捕获组)
                    int i = 0;
                    foreach (Capture c in m.Groups["key2"].Captures)
                    {
                        KeyValuePair<string, string> kv2 = new KeyValuePair<string, string>(c.Value.Trim(), m.Groups["value2"].Captures[i++].Value);
                        if (!kv2.Key.Equals(string.Empty) || !kv2.Value.Equals(string.Empty))
                        {
                            targetList.Add(kv2);
                        }
                    }                if (m.Groups["key3"].Success)
                    {
                        // 匹配到的 else 的 key3 及 value3
                        KeyValuePair<string, string> kv3 = new KeyValuePair<string, string>("1 == 1", m.Groups["value3"].Value);
                        if (!kv3.Key.Equals(string.Empty) || !kv3.Value.Equals(string.Empty))
                        {
                            targetList.Add(kv3);
                        }
                    }
                }
                return targetList;
            }
      

  6.   

    // 可以考虑把正则表达式预编译为程序集,生成正则表达式的 Microsoft 中间语言 (MSIL) 代码;
    // 以较长的启动时间为代价,得到更快的执行速度。   static string pattern = @"(?msix)
    ^(\s*)if\b(? <key1>.*?):(? <value1>.*?)    # 匹配 if 并记录前导空格 
    (^\1elif\b(? <key2>.*?):(? <value2>.*?))*  # 匹配对应的 elif ,0个或多个 
    (^\1else\b(? <key3>.*?):(? <value3>.*?))?  # 匹配对应的 else ,0个或1个 
    \Z                                         # 匹配整个字符串末尾 
    ";
      static Regex regex = new Regex(pattern, RegexOptions.Compiled);  private ArrayList GetLogicFormulaTopLevelIfThenList(string orginalFormulaScript) 
      { 
        ArrayList targetList = new ArrayList(); 
      
        orginalFormulaScript = orginalFormulaScript.Trim().Replace("\r\n", "\n"); 
        MatchCollection mc = regex.Matches(orginalFormulaScript); 
        foreach (Match m in mc) 
        {
          // ... 
        }
      }
      

  7.   

    我在构造里预编译,但是报错。
                pattern = @"(?msix)
    ^(\s*)if\b(? <key1>.*?):(? <value1>.*?)    # 匹配 if 并记录前导空格 
    (^\1elif\b(? <key2>.*?):(? <value2>.*?))*  # 匹配对应的 elif ,0个或多个 
    (^\1else\b(? <key3>.*?):(? <value3>.*?))?  # 匹配对应的 else ,0个或1个 
    \Z                                         # 匹配整个字符串末尾 
    ";
                regex = new Regex(pattern, RegexOptions.Compiled);代码:        static string pattern;
            static Regex regex;        public void SetUp()
            {
                pattern = @"(?msix)
    ^(\s*)if\b(? <key1>.*?):(? <value1>.*?)    # 匹配 if 并记录前导空格 
    (^\1elif\b(? <key2>.*?):(? <value2>.*?))*  # 匹配对应的 elif ,0个或多个 
    (^\1else\b(? <key3>.*?):(? <value3>.*?))?  # 匹配对应的 else ,0个或1个 
    \Z                                         # 匹配整个字符串末尾 
    ";
                regex = new Regex(pattern, RegexOptions.Compiled);
            }
      

  8.   

    System.ArgumentException: 正在分析“(?msix)
    ^(\s*)if\b(? <key1>.*?):(? <value1>.*?)
    (^\1elif\b(? <key2>.*?):(? <value2>.*?))*
    (^\1else\b(? <key3>.*?):(? <value3>.*?))?
    \Z
    ”- 无法识别的分组构造。
      

  9.   

                pattern = @"(?msix)
    ^(\s*)if\b(?<key1>.*?):(?<value1>.*?)    # 匹配 if 并记录前导空格 
    (^\1elif\b(?<key2>.*?):(?<value2>.*?))*  # 匹配对应的 elif ,0个或多个 
    (^\1else\b(?<key3>.*?):(?<value3>.*?))?  # 匹配对应的 else ,0个或1个 
    \Z                                         # 匹配整个字符串末尾 
    ";? 和 <keyX>/<valueX> 之间多了一个空格。
      

  10.   

    CSDN要是有正则表达式的版主就好了...