【问题标题】:regex hour:minute (hour > 24)正则表达式时:分(时 > 24)
【发布时间】:2010-03-11 22:58:53
【问题描述】:

我想在 .NET 中使用正则表达式验证提取小时和分钟从字符串。 只是为了恢复由: 分隔(或不分隔)的两个数字。接受的格式 h:mm。未接受:mh:

编辑: 请注意,小时数可能会溢出 23 到... 32

值小时(超过 32)和分钟(超过 59)的溢出我将在值恢复后(int.Parse)


* 只是为了好玩也许有一个相对简单的正则表达式可以过滤 >32 小时和 >59 分钟(对于 分钟 它可能是[0-5]*[0-9],我不知道几个小时)?

【问题讨论】:

  • 在 Java 中,您只需使用非宽松解析器将字符串解析为 Date 对象并捕获异常(表示失败)。 .NET 中不存在某些东西?
  • 对不起,请提问。没有那种反复试验的态度,你永远学不会真正编码。一旦你真的陷入困境,每个人都很乐意帮助你!
  • @moritz:这不是代码学习。只是一个复杂的正则表达式 IMO。
  • 我建议您阅读更多有关正则表达式的内容,因为这是一项简单的任务。转到regular-expressions.info,当您开始对这个主题感到有点舒服时,您可以使用txt2re.com 等工具。不要更改顺序,否则您仍然无法编写任何正则表达式 - 您必须始终了解您在写什么。
  • @przemoc:感谢您的建议和链接。我知道第一个,有趣的是前者。但是,如果您向所有人发送 expression.info 或 MSDN 正则表达式参考,那么有很多人询问正则表达式,我不知道答案是否会让每个人都满意。你也可以给他们维基百科或一般的互联网访问并告诉他们:搜索和学习:) 谢谢。

标签: .net regex time hour


【解决方案1】:

你对正则表达式死心了吗?因为DateTime.Parse在这里会更简单更强大。

 DateTime dt = DateTime.Parse("12:30 AM");

然后 dt 为您提供有关时间的所有信息。 DateTime.TryParse() 可能会更好,以防您不太确定它是一个时间字符串。

【讨论】:

  • 你可能有理由。首先,我需要排除任何当地文化的影响。其次,我的问题更多地与正则表达式练习有关。
  • 那么你应该通过CultureInfo.InvariantCulture。看我的回答。
  • 我忘了一件小事:maxhour = 32 :)
【解决方案2】:

(?:(\d\d?):)?([0-5][0-9])

如果您想验证小时数:

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

编辑:经过测试和修正。


但是,最好的方法是使用DateTime.ParseExact,如下所示:(已测试)

TimeSpan time = DateTime.ParseExact(
    input, 
    new string[] { "HH:mm", "H:mm", "mm", "%m" }, //The % is necessary to prevent it from being interpreted as a single-character standard format.
    CultureInfo.InvariantCulture, DateTimeStyles.None
).TimeOfDay;

对于验证,您可以使用TryParseExact

【讨论】:

  • 我测试了正则表达式,发现了一些错误,我更正了。
  • @是的。作为其他修复我可以提到DateTime timenew string[]。但是,谢谢,我很欣赏正则表达式和 dateTime 的答案。
  • timeTimeSpan。 (注意TimeOfDay 属性)new [] { } 是 C# 3.0 语法;如果您使用的是 C# 2.0,则需要编写 new string[] { }
  • 只是 "5" 不会解析 "m" DateTime...我用bool result = DateTime.TryParseExact( "5", new string [] { "HH:mm", "H:mm", "mm", "m" }, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);
  • 您需要使用%m。见这里:msdn.microsoft.com/en-us/library/…
【解决方案3】:

这是正则表达式字符串。您可以访问命名的捕获组“小时”和“分钟”。使用标志“ExplicitCapture”和“Singleline”。

@"^((?[0-9]{1,2}):)?(?[0-9]{1,2})$"

您可以在这里测试正则表达式:http://derekslager.com/blog/posts/2007/09/a-better-dotnet-regular-expression-tester.ashx

如前所述,DateTime 解析调用可能会更好,除非您需要验证是否只允许这种形式。

此外,不允许使用负值,也不允许使用小数。 (但是,如果需要,可以更改正则表达式以包含它们)。

【讨论】:

  • hmm... 来自您的测试站点:错误:解析“^((?[0-9]{1,2})\:)?(?[0-9]{1, 2})$" - 无法识别的分组结构。
  • 谢谢 - 已修复。我的尖括号在翻译中丢失了。
【解决方案4】:

最后,验证(直到32)和获取值的代码是(vb.net版本):

Dim regexHour As New Regex( _ 
   "((?<hours>([012]?\d)|(3[01]))\:)?(?<minutes>[0-5]?\d)", _
    RegexOptions.ExplicitCapture)
Dim matches As MatchCollection = regexHour.Matches(value)

If matches.Count = 1 Then
  With matches(0)
    ' (!) The first group is always the expression itself. '
    If .Groups.Count = 3 Then ' hours : minutes '
      strHours = .Groups("hours").Value
      If String.IsNullOrEmpty(strHours) Then strHours = "0"
      strMinutes = .Groups("minutes").Value
    Else ' there are 1, 3 or > 3 groups '
      success = False
    End If
  End With
Else
  success = False
End If

感谢为此答案做出贡献的所有人!

【讨论】:

  • 我认为您将? 量词(零次或一次重复)与* 量词(零次或多次重复)混淆了。
  • @Gumbo:是的。谢谢!已更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-10
  • 2020-04-18
  • 1970-01-01
  • 2013-01-17
相关资源
最近更新 更多