【问题标题】:How to write regex to match equal pairs of delimiters?如何编写正则表达式以匹配相等的分隔符对?
【发布时间】:2020-06-26 14:29:47
【问题描述】:

我有这样的不同日期:

DD-MM-YY
DD.MM.YYYY
YYYY/MM/DD

但日期中的分隔符可以是破折号 - 或点 . 或正斜杠 /

我已经尝试过有效的正则表达式,但我需要检查输入的日期是否使用像 DD-MM/YY 这样的不匹配分隔符然后它应该是无效的,因为第一个分隔符是 - 而第二个分隔符是 /

到目前为止我的尝试:

/^\d\d?\d?\d?[-\/.]\d?\d[-\/.]\d\d?\d?\d?$/.test(userDate)

如何检查第二个分隔符是否与第一个分隔符相同?

【问题讨论】:

  • 使用反向引用,例如([./-]) 用于第一个分隔符,\1 用于第二个分隔符。
  • 您是否还希望正则表达式验证 DD 是 1-31 和 MM 是 1-12 吗?
  • @pretzelhammer 没有
  • 2020/55/2020 这样的东西会通过检查。我想说,一致的分隔符是您对当前方法最不关心的问题。
  • 单独进行某种多阶段验证似乎没有意义,但可以很容易地一起完成。如果您只需要检查分隔符,\d{2}(\d{2})?([.\-\/])\d{2}\2\d{2}(\d{2})? 这样简单的方法就可以了。

标签: javascript regex string date


【解决方案1】:

您可以使用date like pattern,但请注意,这只会缩小可能的匹配范围,并且不会验证日期本身。

要匹配问题中列出的变体,您可以使用 alternation |

要匹配一致的分隔符,您可以使用捕获组 ([-/.]) 和对该组的反向引用 \1\2

如果您不想将年份限制为 19 或 20,您可以将 (?:19|20) 更改为 \d{2}

^(?:(?:19|20)\d\d([-/.])(?:0?[1-9]|1[012])\1(?:0?[1-9]|[12][0-9]|3[01])|(?:0?[1-9]|[12][0-9]|3[01])([-/.])(?:0?[1-9]|1[012])\2(?:19|20)(?:\d\d)?)$

解释

  • ^ 字符串开始
  • (?: 交替的非捕获组
    • (?:19|20)\d\d 匹配 19 或 20 和 2 位数字
    • ([-/.]) 使用 character class 匹配列出的 1 并在 group 1 中捕获
    • (?:0?[1-9]|1[012])\1 带有可选 0 的月份部分和对组 1 的反向引用 \1
    • (?:0?[1-9]|[12][0-9]|3[01]) Day 部分,可选 0
    • |或者
    • 这部分将匹配以年份结尾的年份,年份部分有 2 个可选数字
    • (?:0?[1-9]|[12][0-9]|3[01])([-/.])(?:0?[1-9]|1[012])\2(?:19|20)(?:\d\d)?
  • )关闭非捕获组
  • $字符串结束

Regex demo

【讨论】:

  • 其实我会调查的。似乎它可能会有所帮助
  • 什么是`1[012]?没看懂
  • 这是第 10、11 或 12 个月。这是一个替换 (?:0?[1-9]|1[012]),它匹配前 9 个月的可选零和数字 1-9,或者匹配 10、11 或 12 . 那个机制也被使用了。
  • 如果我输入 1012 作为月份,它会有效吗?
  • 字符类 [12] 匹配 1 或 2。字符类 [0-9] 匹配从 0 到 9 的数字。
【解决方案2】:

使用\d 捕获数字、([-\/.]) 捕获第一个分隔符和正则表达式backreference \1 重新捕获与第一个捕获组中相同的分隔符的工作示例:

function testUserDate(userDate) {
  let regex = /^\d{1,4}([-\/.])\d{1,2}\1\d{1,4}$/;
  return regex.test(userDate);
}

console.log(testUserDate("2007-11-12")); // true
console.log(testUserDate("2007.11.12")); // true
console.log(testUserDate("2007/11/12")); // true
console.log(testUserDate("2007/11-12")); // false
console.log(testUserDate("2007.11/12")); // false
console.log(testUserDate("12-12-2007")); // true
console.log(testUserDate("12/12/2007")); // true
console.log(testUserDate("12.12.2007")); // true
console.log(testUserDate("12/12-2007")); // false
console.log(testUserDate("12-12.2007")); // false

【讨论】:

  • @Thefourthbird 是的,但是 OP 在 cmets 中表示他们只对使用正则表达式匹配一对相等的分隔符感兴趣,并且他们已经有单独的验证代码来检查日、月和年份范围。
【解决方案3】:

如果您希望分隔符保持一致,您可以使用backreference^(19|20)\d\d([- /.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$ 将匹配 1999-01-01 但不匹配 1999/01-01。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多