格式如下:“字符1/字符2/日期/时间/代码/标识/等级”1.字母不区分大小写2.'/'位置可以为任意多的空格(包括0个)'/'本身可有可无3.字符2后面的项的顺序可以任意4.日期后面的项可有可无(可全无,也可以出现任意多项)字符1:两个字母或三个字母 (为三个字母时,第二个字母与第三个之间必须有1个名多个空格加上'/',且字符2前必须为'/'字符2:三个或六个大写字母(三个字母为一组,且这一组是属于指定集合,组与组之间可以有任意空格)日期:格式为:01FEB09(表示09年2月1号,01和feb之间可以有任意多空格)要考虑全法性(比如不是闰年时二月没有二十九)或者为"+","-","."三个字符中的任意一个时间:格式为四位,如12点为1200代码:两个或三个字母组成(代码属于指定集合中的元素)标识:一个或两个字母组成(代码属于指定集合中的元素)等级:一个或两个字母组成(代码属于指定集合中的元素)如下面的将匹配CH H/ABC EFG/23FEB/1100/xy/c/zch /abc efg/23Feb1100ch H/abcefg    23febch abc  efg/23 febch h /abcch abcch abcefg23febch abcefg+chabcefg23feb1100下面的将匹配失败CH H/ABC EFG/29FEB  (因为只有闰年才有29,如改为29FEB08就匹配成功)ch H ABC EFG/20FEB(因为字符1为三个字符时,字符2前发须有"/")chh /abc EGF/20FEB(因为字符1为三个字符时第二和第三个之间必须有"/")ch/ccc EGF/20FEB(如果是ccc不属于指定的集合,则不匹配)ch/abc EGF/20www(因为www不为十二个月的字母缩写)……谢谢大家,用正则表达式或是别的方法都行

解决方案 »

  1.   

    何必弄这么复杂呢
    使用命名分组  (?<tag>.*?)\s*/  或者(?<tag>.*?)\s*(/|$)
     按tag命名分组, 在check就是了. 一个表达式当然能实现,不过这把简单的问题复杂化了,效率底,也不方便维护
      

  2.   

    Regex r = new Regex("(? <tag>.*?)\s*(/|$)", options); //(? <tag>.*?)\s*(/|$)  /|& &主要是匹配行尾的
    MatchCollection ms = r.Matches("字符1/字符2/日期/时间/代码/标识/等级");
      foreach (Match m in ms)
                    {
      
     if(checkGroup(m.Groups["tag"])) //? <tag>表示括号里的内容按tag分组,tag可以随便命名
        .....}建议你下载我写的正则表达式测试器
    http://bfor.cn/xiaoxiao/archive/150067.aspx
    把(? <tag>.*?)\s*(/|$) 填到表达示中,   字符1/字符2/日期/时间/代码/标识/等级 填到内容中
    运行下试试, 另外工具,选项,正则表达示 --显示命名分组勾选上  
      

  3.   


    嗯,这个不取消,基本上是不可能完成的任务
    因为有些规则是是否属于某一集合,所以一个正则也是不可能做到的,整体的思路当然是分组取出后验证,但是由于楼主给出规则的复杂性,分组正则也绝不是一件简单的事
    反正睡不着,就做了一件自讨苦吃的事//验证方法
    private bool CheckRule(string src)
    {
        Match m = Regex.Match(src, @"^\s*[a-zA-Z]{2}\s*(?:[a-zA-Z](?=\s*/))?\s*/?\s*(?<s21>[a-zA-Z]{3})\s*(?<s22>[a-zA-Z]{3})?\s*/?\s*(?:(?<date>\d{2}\s*[a-zA-Z]{3}(?:\d{2})?)|[+-.])?\s*/?\s*(?:(?:[01][0-9]|2[1-3])[0-5][0-9])?(?:\s*/\s*(?<c>[a-zA-Z]{2,3}))?(?:\s*/\s*(?<t>[a-zA-Z]{1,2}))?(?:\s*/\s*(?<l>[a-zA-Z]{1,2}))?\s*$");
        if (m.Success)
        {
            if (m.Groups["s21"].Value.Length != 0)
                if (m.Groups["s21"].Value.ToLower() != "abc")    //验证字符串2的组1是否属于指定集合,根据实际情况调用相关验证方法
                    return false;
            if (m.Groups["s22"].Value.Length != 0)
                if (m.Groups["s22"].Value.ToLower() != "efg")    //验证字符串2的组2是否属于指定集合,根据实际情况调用相关验证方法
                    return false;
            DateTime dt;
            if (m.Groups["date"].Value.Length != 0)             //验证日期是否合法
                if (m.Groups["date"].Value.ToLower() == "29feb" || !DateTime.TryParse(m.Groups["date"].Value.Replace(" ", ""), out dt))
                    return false;
            if (m.Groups["c"].Value.Length != 0)
                if (m.Groups["c"].Value.ToLower() != "xy")    //验证字代码是否属于指定集合,根据实际情况调用相关验证方法
                    return false;
            if (m.Groups["t"].Value.Length != 0)
                if (m.Groups["t"].Value.ToLower() != "c")    //验证标识是否属于指定集合,根据实际情况调用相关验证方法
                    return false;
            if (m.Groups["l"].Value.Length != 0)
                if (m.Groups["l"].Value.ToLower() != "z")    //验证等级是否属于指定集合,根据实际情况调用相关验证方法
                    return false;
        }
        else
            return false;
        return true;
    }
    //调用
    string[] test = new string[] { "CH H/ABC EFG/23FEB/1100/xy/c/z", "ch /abc efg/23Feb1100 ", "ch H/abcefg    23feb", "ch abc  efg/23 feb", "ch h /abc ", "ch abc", "ch abcefg23feb", "ch abcefg+", "chabcefg23feb1100", "CH H/ABC EFG/29FEB", "ch H ABC EFG/20FEB", "chh /abc EGF/20FEB", "ch/ccc EGF/20FEB", "ch/abc EGF/20www" };
    foreach (string s in test)
    {
        richTextBox2.Text += s + "  的验证结果为:  " + (CheckRule(s) ? "成功" : "失败") + "\n";
    }
    //输出
    CH H/ABC EFG/23FEB/1100/xy/c/z  的验证结果为:  成功
    ch /abc efg/23Feb1100   的验证结果为:  成功
    ch H/abcefg    23feb  的验证结果为:  成功
    ch abc  efg/23 feb  的验证结果为:  成功
    ch h /abc   的验证结果为:  成功
    ch abc  的验证结果为:  成功
    ch abcefg23feb  的验证结果为:  成功
    ch abcefg+  的验证结果为:  成功
    chabcefg23feb1100  的验证结果为:  成功
    CH H/ABC EFG/29FEB  的验证结果为:  失败
    ch H ABC EFG/20FEB  的验证结果为:  失败
    chh /abc EGF/20FEB  的验证结果为:  失败
    ch/ccc EGF/20FEB  的验证结果为:  失败
    ch/abc EGF/20www  的验证结果为:  失败字符1和时间的规则已在正则中验证,不做单独验证,这里的时间取的是24小时制但是楼主所给规则,有些是不明确,甚至是自相矛盾的
    字符2:三个或六个大写字母
      但楼主所给匹配成功的例子中却是有小写字母的
    2.'/'位置可以为任意多的空格(包括0个)'/'本身可有可无
      那么在/代码/标识/等级这三项中'/'没有的情况下,由于这三项的长度都是不固定的,比如出现的四个字母“xycz”,那这四个字母分别应该属于哪一项,如何分配,就是不确定的了