首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Regex全日期验证

Regex全日期验证
EN

Stack Overflow用户
提问于 2012-06-07 06:36:00
回答 1查看 6.1K关注 0票数 1

注意:这不是一个关于使用代码进行日期验证的最佳方法的问题,这是一个关于通过一些尝试和错误来学习更多关于正则表达式的问题,以及其他人在网站上的感谢。

最近,我在正则表达式方面做了很多工作(坦白地说,我对它们很烂),我学到了很多东西,我想知道是否有人能就某个特定的正则表达式给出他们的专家意见。

现在,我正在迁移一个相当大的项目来使用.NET 4.0,它有许多跨类和命名空间的解析和数据操作方法。然而,并不是所有的解析和验证都是用大量IndexOf()调用的大量笨拙的for循环完成的。

我已经非常成功地使用了正则表达式、LINQ和扩展方法的组合,以极大地简化和澄清解析和验证方法。

试验和错误以及RegexBuddy极大地帮助了学习曲线。

现在谈我的实际问题。

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

代码语言:javascript
复制
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

代码语言:javascript
复制
private static bool isLikeVCardDate(string value_Renamed)
{
  return Regex.IsMatch(value_Renamed, @"\d{4}-?\d{2}-?d{2}");
}

将符合要求

但这让我思考如何去确认这个日期是一个完全有效的日期,闰年,月中的日子,整个九码。

在“知道”中还有其他关于regex的日期验证的帖子,我不想有人直接给我一个答案,我想知道是否有人可以告诉我如何做得更好或者改进。

请注意,我知道这可能不是使用regex的实际应用程序的最好例子,请记住,我正在努力学习,希望得到一些帮助。

这是我想出的准则

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

此外,所有非命名捕获组都是非捕获组(为了节省空间,我只想让人们对正则表达式进行分析)。

代码语言:javascript
复制
(
 (?<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. Leap年可被4整除,除非它可以被100整除,只有当它也可以被400

整除时

代码语言:javascript
复制
1. Based on this and the fact that ANY number is divisible by 4 if the last 2 digits as a number are divisible by 4
2. Writing out the numbers from 4 - 96 I used the repeating pattern of 0(4,8), {even > 0}(0,4,8) and {odd}(2,6)
3. Since testing for 400 year leap years gives us the first 2 digits of the year being applicable we can us the same pattern from #2 above

  1. 由于闰年的要求,regex需要对闰年的日期和非闰年的日期分别捕获2次。

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

再次,我只是在寻找帮助,以改善在regex,因为我迫切需要让我的头围绕它。

感谢所有花时间阅读这个问题的人。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-06-07 07:30:11

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

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10926793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档