【问题标题】:Finding the best regex pattern for a date format寻找日期格式的最佳正则表达式模式
【发布时间】:2019-06-26 13:30:42
【问题描述】:

我应该检查一个字符串是否匹配某个模式。模式如下

dd.mm.yyyy HH:mm;score;duration
  • 注意 yyy 和 HH 之间的空格
  • score 是一个 int 值
  • duration 是双精度值

如何针对上述问题构建正则表达式模式?我在代码中遗漏了什么或做错了什么?

我主要对分号、冒号、空格键等特殊字符以及何时使用\ 或\\ 感到困惑

public HighscoreEntry(String data) {

    String pattern= "^(3[01]|[12][0-9]|0?[1-9])\\.\\(1[0-2]|0?[1-9])\\.\\(20[0-9]{2})\\s\\(2[0-4]|[01][0-9])\\:\\(5[0-9]|[0-4][0-9]\\;\\d+\\;\\d*\\.\\d+$"; 

    if(data.matches(pattern)){
...

【问题讨论】:

  • 是否需要使用正则表达式?因为通常尝试使用正则表达式来检查日期是否有效并不是最好的方法。 (例如:您如何告诉您的正则表达式 29. 2 月仅在某些特定年份有效?)
  • 要验证您的正则表达式,您可以使用LINK。
  • 如果我理解正确,您不只匹配日期,这是一个日期加上字符串中的 2 个其他值?也许您可以在您的问题中添加一些示例。
  • 这可以是一个(\d{1,2}).(\d{1,2}).(\d{4})\s(\d{1,2}):(\d{1,2});(\d*);(\d*\.\d*) 正则表达式,它可以为您提供所有这些元素。请注意,这不会验证实际日期,例如,如果您在 dd 中得到一个两位数 48,则正则表达式仍将匹配。

标签: java


【解决方案1】:

更轻松的表达方式

^\d{2}\.\d{2}\.\d{4} \d{2}:\d{2};\d+;\d.\d*$

考虑到可能的日期和时间值

^[0-3][0-9]\.[0-1][0-9]\.\d{4} [0-2][0-9]:[0-5][0-9];\d+;\d*.\d*$

要在 Java 字符串中使用它们,每个 \ 都需要用 \ 进行转义,因此 \ -> \\

我没有测试这些模式,所以可能存在一些拼写错误

【讨论】:

    【解决方案2】:

    既然问题是:寻找最好的正则表达式模式而不是什么是最好的正则表达式模式,我将回答这个问题。我使用的技术或多或少是一种分而治之的方法。

    首先,找到分隔符。然后你可以像这样构建你的模式:

    String pattern = field1() + ";" + field2() + "|" + field3(); 
    

    那么您的字段可能具有数据类型。请注意,并非每个(a 的字符串表示)域都是常规的!所以先检查一下。在你的例子中,你想要这样的东西:

    String pattern = intPattern(2) + "\\." + intPattern(2) + "\\." + intPattern(4)
                   + " " + intPattern(2) + ":" + intPattern(2)
                   + ";" + intPattern() + ";" + doublePattern();
    

    intPattern(n) 给出了一个无符号整数的模式,该整数正好是 n 位,intPattern() 给出了一个任意多位的模式。

    优点:

    1. 您可以单独测试模式。
    2. 你不会得到一个看起来像一团糟的超长正则表达式

    但您的示例表明,您需要的不仅仅是验证模式。你想要的是语义。您想检查一下, dd.MM.yyyy 实际上是一个有效日期。这是不可能的,因为正确日期的语言(通常)不规则。如果您只考虑日期的有限子集(例如,从 1990 年到 2400 年),您可以这样做(有限的语言始终是常规的),但这将是一团糟。

    【讨论】:

      猜你喜欢
      • 2012-01-05
      • 1970-01-01
      • 2012-10-09
      • 2012-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多