【问题标题】:Validate timestamp step by step with regex使用正则表达式逐步验证时间戳
【发布时间】:2018-08-11 19:30:50
【问题描述】:

这个正则表达式验证时间戳,例如2018-02-12 00:55:22:

[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]

但是,时间戳应该逐步验证:

201 => true
201a => false
2018- => true
20189 => false

有没有很好的(短)正则表达式扩展?

......

【问题讨论】:

  • step by step 是什么意思?正则表达式仅完全匹配或根本不匹配
  • stackoverflow.com/questions/2524680/… 的可能重复项应该对您有所帮助
  • PHP 不是实时语言。你也不能用 JS 做到这一点(但是有一个workaround here)你正在做的就是部分匹配。
  • Ajax :) 用户类型 2 => true,用户类型 2a => false。你可以使用 html 输入模式。

标签: javascript php regex laravel timestamp


【解决方案1】:

因为您的问题有 javascript 标签,所以我假设您正在进行“onkeyup”或类似的“逐步”验证。以下模式将在构造您的日期时间字符串时对其进行验证(我将一个空字符串包含为有效,以便在为空时不会触发标志;但如果您想对空字符串进行操作,您可以更改为 \d{1,4})。

我尽可能使用\d 来减少模式长度。

x 模式修饰符与我转储的模式一起使用,以便于阅读。当您将它应用到您的项目时,您可以将其全部压缩并删除 x 标志。

我出于习惯使用非捕获组;由于您可能只是匹配,因此您可以根据需要使用捕获组。

Pattern Demo

图案:

~
^
(?:
\d{0,4}|
\d{4}-|
\d{4}-[01]|
\d{4}-(?:0[1-9]|1[0-2])|
\d{4}-(?:0[1-9]|1[0-2])-|
\d{4}-(?:0[1-9]|1[0-2])-[0-3]|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s[0-2]|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d)|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):[0-5]|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):[0-5]\d|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):[0-5]\d:|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):[0-5]\d:[0-5]|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):[0-5]\d:[0-5]\d
)
$
~
x

【讨论】:

【解决方案2】:

您可以将它组合起来以获得 2 个整体信息块。

增量匹配表单分隔符- - : :
同时允许/匹配坏段。

最后,您会获得有关表单进度的信息。
还有表格段。

您通过捕获组 2、4、6、8、10 测试表单的进度

您通过组 1、3、5、7、9、11 测试日期/时间元素

不过,您只需要测试表单中最大组的元素
进展。

^(?:(?:([0-9]{4})|\d*)(-(?:(0[1-9]|1[0-2])|\d*)(-(?:(0[1-9]|[1-2][0-9]|3[0-1])|\d*)([ ]+(?:(2[0-3]|[01][0-9])|\d*)(:(?:([0-5][0-9])|\d*)(:(?:([0-5][0-9])|\d*))?)?)?)?)?)$

格式化

 ^    
 (?:
      (?:
           ( [0-9]{4} )                          # (1)
        |  \d* 
      )
      (                                     # (2 start)
           -
           (?:
                ( 0 [1-9] | 1 [0-2] )                 # (3)
             |  \d* 
           )
           (                                     # (4 start)
                -
                (?:
                     ( 0 [1-9] | [1-2] [0-9] | 3 [0-1] )   # (5)
                  |  \d* 
                )
                (                                     # (6 start)
                     [ ]+ 
                     (?:
                          ( 2 [0-3] | [01] [0-9] )              # (7)
                       |  \d* 
                     )
                     (                                     # (8 start)
                          :
                          (?:
                               ( [0-5] [0-9] )                       # (9)
                            |  \d* 
                          )
                          (                                     # (10 start)
                               :
                               (?:
                                    ( [0-5] [0-9] )                       # (11)
                                 |  \d* 
                               )
                          )?                                    # (10 end)
                     )?                                    # (8 end)
                )?                                    # (6 end)
           )?                                    # (4 end)
      )?                                    # (2 end)
 )
 $

如果捕获组匹配,则通过分段。

【讨论】:

  • 几乎,几乎:)
【解决方案3】:

正则表达式不是这样做的方法。

这是一个简单的功能。你用正确格式的好日期,去掉前面输入的字符数,并与输入的值结合,然后检查它是否有效

function validateDate($date)
{
    $fakedate = "2018-02-12 00:55:22";
    $date .= substr($fakedate, strlen($date));
    $format = 'Y-m-d H:i:s';
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}

var_dump(validateDate('201')); bool(true)
var_dump(validateDate('201a')); bool(false)
var_dump(validateDate('2018-')); bool(true)
var_dump(validateDate('20189')); bool(false)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 1970-01-01
    相关资源
    最近更新 更多