1

请注意,这不是关于使用代码进行日期验证的最佳方式的问题,而是关于通过一些试验和错误了解更多关于正则表达式的问题以及其他人在此感谢您。

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

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

我一直在非常成功地使用正则表达式、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);
}

如果我想匹配该功能一个简单的正则表达式

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 > 0}(0,4,8) 和 {odd}(2,6) 的重复模式

    3. 由于对 400 年闰年的测试为我们提供了适用年份的前 2 位数字,我们可以使用上面 #2 中的相同模式

  3. 由于闰年的要求,正则表达式需要 2 次单独捕获闰年的日期和非闰年的日期。

现在我所有的假设都可能是错误的,只是简单明了,但这是我能想出的,到目前为止我对正则表达式的理解程度

同样,我只是在寻求帮助以改进正则表达式,因为我迫切需要了解它。

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

4

1 回答 1

2

我知道您这样做是为了学习正则表达式,因此您可能会喜欢了解这些其他问题的答案中的示例如何工作:

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

于 2012-06-07T07:30:11.860 回答