正則表達式應用(日期正則表達式)

 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)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-/.]?)0?2([-/.]?)29)$

使用反向引用進行簡化,年份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[0-2])\1(?:29|30)|(?:0?[13578]|1[02])\1(?:31))|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-/.]?)0?2\2(?:29))$

這就是“年月日”這種形式最全的一個正則了,不同含義部分以不同顏色標識,可以根據自己的需要進行栽剪。

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([-/.]?)(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00))$

這種格式需要注意的就是不能用反向引用來進行優了。連字符等可根據自己的需求栽剪。

4.3 添加時間的擴展
時間的規格很明確,也很簡單,基本上就HH:mm:ss和H:m:s兩種形式。

([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]

合入到日期的正則中,yyyy-MM-dd HH:mm:ss

^(?:(?!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)\s+([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$

4.4 年份定製
以上所有涉及到平年的年份裏,使用的是0001-9999。當然,年份也可以根據閏年規則定製。

如年份1600-9999,格式yyyy-MM-dd或yyyy-M-d,連字符可以沒有或是“-”、“/”、“.”之一。

^(?:(?:1[6-9]|[2-9][0-9])[0-9]{2}([-/.]?)(?:(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[0-2])\1(?:29|30)|(?:0?[13578]|1[02])\1(?:31))|(?:(?:1[6-9]|[2-9][0-9])(?:0[48]|[2468][048]|[13579][26])|(?:16|[2468][048]|[3579][26])00)([-/.]?)0?2\2(?:29))$

5 特別說明
以上正則採用的是最基本的正則語法規則,絕大多數採用傳統NFA引擎的語言都可以支持,包括JavaScript、Java、.NET等。

另外需求說明的是,雖然日期的規則相對明確,可以採用這種方式裁剪來得到符合要求的日期正則,但是並不推薦這樣使用正則,正則的強大在於它的靈活性,可以根據需求,量身打造最合適的正則,如果只是用來套用模板,那正則也就不稱其爲正則了。

正則的語法規則並不多,而且很容易入門,掌握語法規則,量體裁衣,纔是正則之“道”。

view plaincopy to clipboardprint?
DateTime dt = new DateTime(1, 1, 1);
DateTime endDay = new DateTime(9999, 12, 31);
Stopwatch sw = new Stopwatch();
sw.Start();
Regex dateRegex = new Regex(@"^(?:(?!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)$");
//Regex dateRegex = new Regex(@"^((?!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)$");
Console.WriteLine("開始日期: " + dt.ToString("yyyy-MM-dd"));
while (dt <= endDay)
{
if (!dateRegex.IsMatch(dt.ToString("yyyy-MM-dd")))
{
Console.WriteLine(dt.ToString("yyyy-MM-dd") + " false");
}
if (dt == endDay)
{
break;
}
dt = dt.AddDays(1);
}
Console.WriteLine("結束日期: " + dt.ToString("yyyy-MM-dd"));
sw.Stop();
Console.WriteLine("測試用時: " + sw.ElapsedMilliseconds + "ms");
Console.WriteLine("測試完成!");
Console.ReadLine();
DateTime dt = new DateTime(1, 1, 1); DateTime endDay = new DateTime(9999, 12, 31); Stopwatch sw = new Stopwatch(); sw.Start(); Regex dateRegex = new Regex(@"^(?:(?!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)$"); //Regex dateRegex = new Regex(@"^((?!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)$"); Console.WriteLine("開始日期: " + dt.ToString("yyyy-MM-dd")); while (dt <= endDay) { if (!dateRegex.IsMatch(dt.ToString("yyyy-MM-dd"))) { Console.WriteLine(dt.ToString("yyyy-MM-dd") + " false"); } if (dt == endDay) { break; } dt = dt.AddDays(1); } Console.WriteLine("結束日期: " + dt.ToString("yyyy-MM-dd")); sw.Stop(); Console.WriteLine("測試用時: " + sw.ElapsedMilliseconds + "ms"); Console.WriteLine("測試完成!"); Console.ReadLine();

view plaincopy to clipboardprint?
for (int i = 1; i < 10000; i++)
{
if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0)
{
richTextBox2.Text += string.Format("{0:0000}", i) + "\n";
}
}
for (int i = 1; i < 10000; i++) { if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) { richTextBox2.Text += string.Format("{0:0000}", i) + "\n"; } }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章