正则表达式完整日期验证

时间:2012-06-07 06:36:00

标签: c# regex validation date

请注意,这不是一个关于什么是代码最佳方式的问题日期验证 这是一个关于通过一些试验和错误以及其他人参与了解更多关于正常表达的问题 谢谢。

我最近一直在用正则表达式做很多工作(坦白地说,我很嘲笑他们)我虽然学到了很多东西,但我想知道是否有人可以就特定的正则表达方式给出他们的专家意见。 / p>

现在我正在努力迁移一个相当大的项目以使用.NET 4.0它在许多类和命名空间中有很多解析和数据操作方法......但是大多数并非所有的解析和验证都有已经完成了大量笨重的for循环与大量的IndexOf()调用。

我一直非常成功地使用正则表达式,LINQ和扩展方法的组合来大大简化和澄清解析和验证方法。

试验和错误以及RegexBuddy对学习曲线的帮助非常大。

现在谈谈我的实际问题。

我正在努力更新简单的日期验证,尽管这是一个非常非常松散的验证

private static bool isLikeVCardDate(string value_Renamed)
{
  if (value_Renamed == null)
  {
    return true;
  }
  // Not really sure this is true but matches practice
  // Mach YYYYMMDD
  if (isStringOfDigits(value_Renamed, 8))
  {
    return true;
  }
  // or YYYY-MM-DD
  return value_Renamed.Length == 10 && value_Renamed[4] == '-' && value_Renamed[7] == '-' && isSubstringOfDigits(value_Renamed, 0, 4) && isSubstringOfDigits(value_Renamed, 5, 2) && isSubstringOfDigits(value_Renamed, 8, 2);
}

如果我想将该功能与

的简单RegEx相匹配
private static bool isLikeVCardDate(string value_Renamed)
{
  return Regex.IsMatch(value_Renamed, @"\d{4}-?\d{2}-?d{2}");
}

符合要求

但它让我思考如何确认日期是完全有效的日期,闰年,整个九码的月份

知道还有其他关于日期验证与正则表达式的帖子我对一个人没有兴趣直接给我一个答案我已经工作了我想知道是否有任何知识可以传授给我如何可能做得更好或改进它。

请注意,我知道这可能不是使用正则表达式的实际应用的最佳示例,请记住我在这里学习并希望得到一些帮助

这是我提出的正则表达式

为了简化阅读,我在“选项卡式”视图中粘贴了一些注释,实际的正则表达式没有空格或新行。

此外,不是命名捕获组的所有内容都是非捕获组(因为我只想让人们对正则表达式进行分析,所以我将其留空以节省空间)

(
 (?<YEAR>((([0][48])|([13579][26])|([2468][048]))00)|(\d{2}(([0][48])|([13579][26])|([2468][048]))))
 -?
 (
  (
   (?<MONTH>(0[13578])|( 1[02]))
   -?
   (?<DAY>(0[1-9])|([12][0-9])|(3[01]))
  )
  |
  (
   (?<MONTH>(0[469])|11)
   -?
   (?<DAY>(0[1-9])|([12][0-9])|30)
  )
  |
  (
   (?<MONTH>02)
   -?
   (?<DAY>(0[1-9])|([12][0-9]))
  )
 )
)
|
(
 (?<YEAR>\d{4})
 -?
 (
  (
   (?<MONTH>(0[13578])|(1[02]))
   -?
   (?<DAY>(0[1-9])|([12][0-9])|(3[01]))
  )
  |
  (
   (?<MONTH>(0[469])|11)
   -?
   (?<DAY>(0[1-9])|([12][0-9])|30)
  )
  |
  (
   (?<MONTH>02)
   -?
   (?<DAY>(0[1-9])|(1[0-9])|(2[0-8]))
  ) 
 )
)

这是我的思考过程

  1. 天数相对于月份4,6,9,11为30天| 1,3,5,7,8,10,12有31和2有28或29

  2. 闰年可被四除尽,除非它可以被100整除,然后才能被400整除

    1. 基于此以及如果最后2位数作为数字可被4整除则任意数字可被4整除的事实

    2. 写出4到96之间的数字我使用了重复模式0(4,8),{even&gt; 0}(0,4,8)和{odd}(2,6)

    3. 由于400年闰年的测试为我们提供了今年的前2位数字,我们可以使用与#2相同的模式

  3. 由于闰年要求,正则表达式需要2个单独的捕获日期为闰年,日期不是闰年。

  4. 现在我的所有假设都可能是错误的,只是在那里,但是我能想出到目前为止我对正则表达式有多了解

    我再次寻求帮助改善正则表达式,因为我迫切需要把头缠在它上面。

    非常感谢那些花时间阅读这个问题的人。

1 个答案:

答案 0 :(得分:2)

我知道你这样做是为了练习正则表达式,所以你可能会喜欢弄清楚这些其他问题的答案中的例子是如何工作的:

当然,要学习正则表达式最重要的一课就是不使用它们。因此,我认为您可能很难获得有关您发布的示例的详细反馈。这里带回家的教训是,虽然有些人喜欢写复杂的正则表达式,但很少有人喜欢阅读(或扩展或修复)它们。