【问题标题】:Regex to allow separator only when both parts are present正则表达式仅在两个部分都存在时才允许分隔符
【发布时间】:2025-11-25 04:45:01
【问题描述】:

目前我正在编写一个正则表达式来验证日期时间字符串。基本格式是

(Date)(?: *,?)(Time) 

我已经很好地计算出正则表达式的日期和时间部分,但我无法让正则表达式允许所有这三种情况:

  • 日期,无分隔符,无时间
  • 日期、分隔符和时间
  • 没有日期,没有分隔符和时间

简单的方法(使所有三个部分都是可选的)具有允许案例的意外副作用

  • 没有日期和分隔符,也没有时间

这可以通过环视来实现吗?

有效输入示例:

  • January 25 2004, 10:30 PM
  • 2004-1-25
  • 10:30 PM

输入无效:

  • ,

(日期和时间正则表达式处理一堆情况,我已经解决了 - 它可以防止无效的情况,同时允许我仍然需要的所有三种形式。)

【问题讨论】:

  • @Avinash - 我添加了一些示例。

标签: regex datetime regex-lookarounds


【解决方案1】:

如果您在日期或时间组中包含分隔符,则分隔符本身将不匹配:

^(DATE(?: *,? *))?(TIME)?$

它有一个可选的日期和分隔符,后跟一个可选的时间。

查看演示:http://regex101.com/r/dH6nI2/1

【讨论】:

  • 我将使用捕获组作为分隔符,因此第 1 组和第 3 组包含日期和时间,现在分隔符将包含在第一个匹配组中。
  • 你完全正确——我把事情复杂化了。谢谢。
【解决方案2】:

你可以使用交替:

((Date)((?: *,?)(Time))?|((Date)(?: *,?))?(Time))

虽然这会导致一些重复。

【讨论】:

  • 这需要重复正则表达式的日期和时间部分,对吧?我试图避免这种情况,因为它已经很长了。我想我找到了一个解决方案,很快就会发布。
【解决方案3】:

我想我找到了一个可行的解决方案。我在开头使用前瞻来验证它不是以分隔符开头...然后使分隔符成为时间部分的可选部分。

/^(?=[A-Za-z0-9])(Date)(?:(?:Separator)?(Time))$/

例如,要使用YYYY-MM-DD 格式的日期和HH:ii 格式的时间和, *| + 分隔符(可选逗号和一个或多个空格)来验证日期时间,它将是

/^(?=[0-9])(?:([0-9]{4})-([0-9]{2})-([0-9]{2}))?(?:(?:, *| +)?([0-9]{2}:[0-9]{2}))?$/

【讨论】:

  • 你可以使用 Negative Lookahead,^(?!Sep$)(Date)?(?:Sep)?(Time)?$
  • @Avinash - 它失败了,因为我在答案中给出的示例不包括对月份字符串版本的支持。为了简化示例正则表达式,我没有包含它。
  • @hwnd 谢谢!我猜对非分隔符的前瞻和对分隔符的否定前瞻是同一枚硬币的两个面。
最近更新 更多