Regex完整日期验证

ocebsuys  于 2023-04-13  发布在  其他
关注(0)|答案(1)|浏览(81)

(Note:这不是一个关于用代码进行日期验证的最佳方法的问题。这是一个关于通过一些尝试和错误以及其他人的洞察力来学习更多关于正则表达式的问题。)
我最近在正则表达式方面做了很多工作(坦白地说,我在这方面很糟糕),不过我学到了很多东西,我正在寻求Maven对特定正则表达式的意见。
现在我正在迁移一个相当大的项目使用.NET 4.0它有很多解析和数据操作方法,跨越许多类和命名空间......然而,大多数的解析和验证都是用大量的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);
}

如果我想匹配该功能,可以使用

private static bool isLikeVCardDate(string value_Renamed)
{
  return Regex.IsMatch(value_Renamed, @"\d{4}-?\d{2}-?d{2}");
}

是否符合要求
但这让我思考,我该如何验证日期是完全有效的日期,闰年,月份的日期,所有的九码
我知道还有其他关于regex日期验证的帖子,我对有人直接给我答案不感兴趣,我已经得到了它的工作,我想知道是否有任何人可以传授给我任何知识,也许如何做得更好或改进它。
请注意,我知道这可能不是使用正则表达式的实际应用的最佳示例。
这是我想出来的正则表达式。
为了便于阅读,我在“选项卡式”视图中粘贴了一些注解,实际的正则表达式没有空格或新行。
另外,所有不是NamedCaptureGroup的内容都是非捕获组(为了保存空间,我把它去掉了,因为我只想让人们分析正则表达式)

(
 (?<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
1.闰年可以被4整除,除非它可以被100整除,那么只有当它也可以被400整除
1.基于这一点和事实,任何数字是可分的4,如果最后2位数作为一个数字是可分的4
1.写出4 - 96的数字时,我使用了0(4,8)、{偶〉0}(0,4,8)和{奇}(2,6)的重复模式。
1.由于测试400年闰年给我们的前2位数字的一年是适用的,我们可以我们从上面的#2相同的模式
1.由于闰年的要求,正则表达式需要两个单独的捕获日期在闰年和日期不在闰年。
现在我所有的假设都可能是错的,就在那里,但这是我能想到的,到目前为止,我对正则表达式的理解有多少

vdgimpew

vdgimpew1#

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

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

相关问题