格式如下:“字符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不为十二个月的字母缩写)……谢谢大家,用正则表达式或是别的方法都行
使用命名分组 (?<tag>.*?)\s*/ 或者(?<tag>.*?)\s*(/|$)
按tag命名分组, 在check就是了. 一个表达式当然能实现,不过这把简单的问题复杂化了,效率底,也不方便维护
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/日期/时间/代码/标识/等级 填到内容中
运行下试试, 另外工具,选项,正则表达示 --显示命名分组勾选上
嗯,这个不取消,基本上是不可能完成的任务
因为有些规则是是否属于某一集合,所以一个正则也是不可能做到的,整体的思路当然是分组取出后验证,但是由于楼主给出规则的复杂性,分组正则也绝不是一件简单的事
反正睡不着,就做了一件自讨苦吃的事//验证方法
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”,那这四个字母分别应该属于哪一项,如何分配,就是不确定的了