正则表达式日期正则应用的 日期正则表达式
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$
以上正则年份0001-9999格式yyyy-MM-dd可以通过以下代码验证正则有效性和性能 复制代码 代码如下: DateTime dt = DateTime(1, 1, 1); DateTime endDay = DateTime(9999, 12, 31); Stopwatch sw = Stopwatch; sw.Start; Regex dateRegex = Regex(@"^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[139]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[09]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$"); //Regex dateRegex = Regex(@"^((?!0000)[0-9]{4}-((0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])|(0[13-9]|1[02])-(29|30)|(0[13578]|1[02])-31)|([09]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00)-02-29)$"); Console.WriteLine("开始日期: " + dt.("yyyy-MM-dd")); while (dt <= endDay) { (!dateRegex.IsMatch(dt.("yyyy-MM-dd"))) { Console.WriteLine(dt.("yyyy-MM-dd") + " false"); } (dt endDay) { ; } dt = dt.AddDays(1); } Console.WriteLine("结束日期: " + dt.("yyyy-MM-dd")); sw.Stop; Console.WriteLine("测试用时: " + sw.ElapsedMilliseconds + "ms"); Console.WriteLine("测试完成!"); Console.ReadLine;
正则表达式日期:正则应用的 日期正则表达 式
疯狂代码 http://CrazyCoder.cn/ ĵ:http:/CrazyCoder.cn/DeveloperUtil/Article69992.html 1概述 首先需要介绍说明点无论是Winform还是Webform都有很成熟日历Control控件无论从易用性还是可扩展性上 看日期选择和校验还是用日历Control控件来实现比较好 前几天在CSDN多个版块看到需要日期正则帖子所以整理了这篇文章和大家起讨论交流如有遗漏或地方还请大 家指正 日期正则般是对格式有要求且数据不是直接由用户输入时使用因应用场景区别写出正则也区别复杂程度也自然 区别正则书写需要根据具体情况具体分析个基本原则就是:只写合适不写复杂 对于日期提取只要能和非日期区分开写最简单正则即可如 复制代码 代码如下: \d{4}-\d{2}-\d{2}
合起来就是除闰年2月29日外其它所有日期 复制代码 代码如下: (?!0000)[0-9]{4}-((0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])|(0[13-9]|1[0-2])-(29|30)|(0[13578]|1[02])-31)
接下来考虑闰年实现 Ø 闰年2月包含29日 这里月和日是固定就是02-29只有年是变化 可通过以下代码输出所有闰年年份考察规则 复制代码 代码如下: for ( i = 1; i < 10000; i) { ((i % 4 0 && i % 100 != 0) || i % 400 0) {
这就是“年月日”这种形式最全个正则了区别含义部分以区别颜色标识可以根据自己需要进行栽剪 4.2 其它形式扩展 了解了以上正则各部分代表含义互相间关系后就很容易扩展成其它格式日期正则如dd/MM/yyyy这种“日月年 ”格式日期 复制代码 代码如下: ^(?:(?:(?:0?[1-9]|1[0-9]|2[0-8])([-/.]?)(?:0?[1-9]|1[0-2])|(?:29|30)([-/.]?)(?:0?[13-9]|1[0-2])|31([/.]?)(?:0?[13578]|1[02]))([-/.]?)(?!0000)[0-9]{4}|29([-/.]?)0?2([-/.]?)(?:[09]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00))$
使用反向引用进行简化年份0001-9999格式yyyy-MM-dd或yyyy-M-d连可以没有或是“-”、“/”、“.”的 复制代码 代码如下: ^(?:(?!0000)[0-9]{4}([-/.]?)(?:(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[02])\1(?:29|30)|(?:0?[13578]|1[02])\1(?:31))|(?:[09]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-/.]?)0?2\2(?:29))$
考虑到这个正则表达式仅仅是用作验证所以捕获组没有意义只会占用资源影响匹配效率所以可以使用非捕获组 来进行优化 复制代码 代码如下: ^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-
合起来就是所有闰年2月29日 复制代码 代码如下: ([0-9]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00)-02-29)
4条规则都已实现且互相间没有影响合起来就是所有符合DateTime范围日期正则 复制代码 代码如下: ^((?!0000)[0-9]{4}-((0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])|(0[13-9]|1[0-2])-(29|30)|(0[13578]|1[02])31)|([0-9]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00)-02-29)$
如果可以在源串中唯定位yyyy-MM-dd格式日期则可用做提取 对于验证如果仅仅是验证组成及格式是没有多大意义还要加入对规则校验由于闰年存在使得日期校验正则变得 比较复杂 先来考察下日期有效范围以及什么是闰年 2 日期规则 2.1 日期有效范围 对于日期有效范围区别应用场景会有所区别 MSDN中定义DateTime对象有效范围是:0001-01-01 00:00:00到9999-12-31 23:59:59 UNIX时间戳0按照ISO 8601规范标准为 :1970-01-01T00:00:00Z 而实际应用中日期范围基本上不会超出DateTime所规定范围所以正则验证取其中常用日期范围即可 2.2 什么是闰年 (以下摘自百度百科) 闰年(leap year)是为了弥补因人为历法规定造成年度天数和地球实际公转周期时间差而设立补上时间差年份为 闰年 地球绕日运行周期为365天5小时48分46秒(合365.24219天)即回归年(tropical year)公历平年只有365日比回归 年短约0.2422 日每 4年累积约天把这天加于2月末(即2月29日)使当年时间长度变为366日这年就为闰年 需要注意是,现在公历是根据罗马人“儒略历”改编而得由于当时没有了解到每年要多算出0.0078天问题从公元 前46年到16世纪共累计多出了10天为此当时教皇格雷果里十 3世将1582年10月5日人为规定为10月15日并开 始了新闰年规定即规定公历年份是整百数必须是400倍数才是闰年不是400倍数就是平年比如1700年、1800年 和1900年为平年2000年为闰年此后平均每年长度为365.2425天约4年出现1天偏差按照每 4年个闰年计算平均
下面仅考虑月和日正则 Ø 包括平年在内所有年份月份都包含1-28日 复制代码 代码如下: (0Leabharlann Baidu1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])
Ø 包括平年在内所有年份除2月外都包含29和30日 复制代码 代码如下: (0[13-9]|1[0-2])-(29|30)
Ø 包括平年在内所有年份1、3、5、7、8、10、12月都包含31日 复制代码 代码如下: (0[13578]|1[02])-31)
每年就要多算出0.0078天经过 4百年就会多出大约3天来因此每 4百年中要减少 3个闰年闰年计算归结起来就是 通常说: 4年闰;百年不闰 4百年再闰 2.3 日期格式 根据区别语言文化日期连会有所区别通常有以下几种格式: yyyyMMdd yyyy-MM-dd yyyy/MM/dd yyyy.MM.dd 3 日期正则表达式构建 3.1 规则分析 写复杂正则个常用思路方法就是先把不相关需求拆分开分别写出对应正则然后组合检查下相互关联关系以及影 响基本上就可以得出对应正则 按闰年定义可知日期可以有几种分类思路方法 3.1.1 根据天数是否和年份有关划分为两类 和年份无关类中根据每月天数区别又可细分为两类 Ø 1、3、5、7、8、10、12月为1-31日 Ø 4、6、9、11月为1-30日 和年份有关类中 Ø 平年2月为1-28日 Ø 闰年2月为1-29日 3.1.2 根据包含日期区别可划分为 4类 Ø 所有年份所有月份都包含1-28日 Ø 所有年份除2月外都包含29和30日 Ø 所有年份1、3、5、7、8、10、12月都包含31日 Ø 闰年2月包含29日 3.1.3 分类思路方法选择 日期分类的后实现是要通过(exp1|exp2|exp3)这种分支结构来实现而分支结构是从左侧分支依次向右开始尝试 匹配当有个分支匹配成功时就不再向右尝试否则尝试所有分支后并报告失败 分支多少每个分支复杂程度都会影响匹配效率考虑到被验证日期概率分布绝大多数都是落到1-28日内所以采用 第 2种分类思路方法会有效提高匹配效率 3.2 正则实现 采用3.1.2节分类思路方法就可以针对每个规则写出对应正则以下暂按MM-dd格式进行实现 先考虑和年份无关前 3条规则年份可统写作 复制代码 代码如下: (?!0000)[0-9]{4}
4 日期正则表达式扩展 4.1 “年月日”形式扩展 以上实现是yyyy-MM-dd格式日期验证考虑到连区别以及月和日可能为M和d即yyyy-M-d格式可以对以上正则 进行扩展 复制代码 代码如下: ^(?:(?!0000)[0-9]{4}([-/.]?)(?:(?:0?[1-9]|1[0-2])([-/.]?)(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[0-2])([/.]?)(?:29|30)|(?:0?[13578]|1[02])([-/.]?)31)|(?:[09]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-/.]?)0?2([-/.]?)29)$
richTextBox2.Text .Format("{0:0000}", i) + "\n"; } }
根据闰年规则很容易整理出规则 4年闰; 复制代码 代码如下: ([0-9]{2}(0[48]|[2468][048]|[13579][26])
百年不闰 4百年再闰 复制代码 代码如下: (0[48]|[2468][048]|[13579][26])00