评估日期范围的正则表达式

Regex to evaluate Date Range

我有一个 UNIX ls 输出并且必须将正则表达式写入 return 日期范围大于 2017-11-05 的文件名。

我知道正则表达式不适用于数值计算,但我使用的工具只支持模式,这就是为什么我唯一的选择是正则表达式。

示例输入如下:

https://regex101.com/r/shFymy/2

drwxrwxr-x - testetl hdp_test 0 2018-02-02 05:10 /raw/ADS/ClicksData/click/datetm=2017-10-15 drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:35 /raw/ADS/ClicksData/click/datetm=2017-10-16 drwxrwxr-x - testetl hdp_test 0 2018-01-31 21:54 /raw/ADS/ClicksData/click/datetm=2017-10-17 drwxrwxr-x - testetl hdp_test 0 2018-01-31 23:59 /raw/ADS/ClicksData/click/datetm=2017-10-18 drwxrwxr-x - testetl hdp_test 0 2018-01-31 21:49 /raw/ADS/ClicksData/click/datetm=2017-10-19 drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:32 /raw/ADS/ClicksData/click/datetm=2017-10-20 drwxrwxr-x - testetl hdp_test 0 2018-02-02 11:51 /raw/ADS/ClicksData/click/datetm=2017-10-21 drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:08 /raw/ADS/ClicksData/click/datetm=2017-10-22 drwxrwxr-x - testetl hdp_test 0 2018-01-31 22:42 /raw/ADS/ClicksData/click/datetm=2017-10-23 drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:58 /raw/ADS/ClicksData/click/datetm=2017-10-24 drwxrwxr-x - testetl hdp_test 0 2018-02-02 05:10 /raw/ADS/ClicksData/click/datetm=2017-10-25 drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:46 /raw/ADS/ClicksData/click/datetm=2017-10-26 drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:04 /raw/ADS/ClicksData/click/datetm=2017-10-27 drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:46 /raw/ADS/ClicksData/click/datetm=2017-10-28 drwxrwxr-x - testetl hdp_test 0 2018-02-02 00:21 /raw/ADS/ClicksData/click/datetm=2017-10-29 drwxrwxr-x - testetl hdp_test 0 2018-02-02 05:09 /raw/ADS/ClicksData/click/datetm=2017-10-30 drwxrwxr-x - testetl hdp_test 0 2018-02-02 05:13 /raw/ADS/ClicksData/click/datetm=2017-10-31 drwxrwxr-x - testetl hdp_test 0 2018-02-01 14:34 /raw/ADS/ClicksData/click/datetm=2017-11-01 drwxrwxr-x - testetl hdp_test 0 2018-02-02 09:20 /raw/ADS/ClicksData/click/datetm=2017-11-02 drwxrwxr-x - testetl hdp_test 0 2018-02-01 14:35 /raw/ADS/ClicksData/click/datetm=2017-11-03 drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:42 /raw/ADS/ClicksData/click/datetm=2017-11-04 drwxrwxr-x - testetl hdp_test 0 2018-02-02 09:18 /raw/ADS/ClicksData/click/datetm=2017-11-05 drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:11 /raw/ADS/ClicksData/click/datetm=2017-11-06 drwxrwxr-x - testetl hdp_test 0 2018-01-31 17:56 /raw/ADS/ClicksData/click/datetm=2017-11-07 drwxrwxr-x - testetl hdp_test 0 2018-01-31 21:36 /raw/ADS/ClicksData/click/datetm=2017-11-08 drwxrwxr-x - testetl hdp_test 0 2018-01-31 16:43 /raw/ADS/ClicksData/click/datetm=2017-11-09 drwxrwxr-x - testetl hdp_test 0 2018-01-31 21:59 /raw/ADS/ClicksData/click/datetm=2017-11-10 drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:23 /raw/ADS/ClicksData/click/datetm=2017-11-11

示例输出如下:

drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:11 /raw/ADS/ClicksData/click/datetm=2017-11-06 drwxrwxr-x - testetl hdp_test 0 2018-01-31 17:56 /raw/ADS/ClicksData/click/datetm=2017-11-07 drwxrwxr-x - testetl hdp_test 0 2018-01-31 21:36 /raw/ADS/ClicksData/click/datetm=2017-11-08 drwxrwxr-x - testetl hdp_test 0 2018-01-31 16:43 /raw/ADS/ClicksData/click/datetm=2017-11-09 drwxrwxr-x - testetl hdp_test 0 2018-01-31 21:59 /raw/ADS/ClicksData/click/datetm=2017-11-10 drwxrwxr-x - testetl hdp_test 0 2018-02-01 09:23 /raw/ADS/ClicksData/click/datetm=2017-11-11

为了 return 以晚于 2017 年 11 月 5 日的日期结束的整行,您可以使用 this regex:

^.*=(?:2017-(?:11-(?:0[6-9]|[12][0-9]|30)|12-\d{2})|2018-\d{2}-\d{2})

符合3种情况:

  • 2017 年 11 月的日期,从 5 号开始
  • 2017 年 12 月的日期
  • 2018 年日期

您没有具体说明输入的正确性,所以我假设所有日期都有效(即不是 2018-45-90

你可以试试这个,可能就是你要问的。

注意这不是日期验证
这只是一个大于日期的验证。

需要更多的正则表达式(包括闰年) 验证日期。但是,我不认为这是你需要的。

https://regex101.com/r/AE0g7o/1

(?m)^.*(?:(?:201[89]|2\d[2-9]\d|[3-9]\d{3})-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])|2017-(?:12-(?:0[1-9]|[12]\d|3[01])|11-(?:0[6-9]|[12]\d|3[01])))$

请注意,如果将所有 01 - 31 和 01 - 12 替换为 \d{2}

,则可以缩短它

格式化

 (?m)                          # Multi-line mode 
 ^                             # BOL
 .* 
 (?:
      (?:                           # 2018 - 9999
           201 [89] 
        |  2 \d [2-9] \d 
        |  [3-9] \d{3} 
      )
      -                            
      (?: 0 [1-9] | 1 [0-2] )       # 01 - 12
      - 
      (?:                           # 01 - 31
           0 [1-9]                     
        |  [12] \d 
        |  3 [01] 
      )
   |                              # OR,

      2017                          # 2017
      -
      (?:
           12 -                          # 12    
           (?:                           # 01 - 31
                0 [1-9]                     
             |  [12] \d 
             |  3 [01] 
           )

        |                              # or,
           11 -                          # 11
           (?:                           # 06 - 31
                0 [6-9] 
             |  [12] \d 
             |  3 [01] 
           )
      )
 )
 $                             # EOL

缩短版本,仍然只验证大于日期

(?m)^.*(?:(?:201[8-9]|2\d[2-9]\d|[3-9]\d{3})-\d{2}-\d{2}|2017-(?:12-\d{2}|11-(?:0[6-9]|[12]\d|3[01])))$

https://regex101.com/r/wtL0Hx/1

您尝试使用正则表达式是在给自己添麻烦。不确定您使用的是什么工具,但我确定还有其他选择:

  • 如果它类似于 shell 脚本,只需将输入日期转换为 Unix 时间戳,例如

    $ date -u -d '2017-11-06' +%s
    1509926400
    

    然后你有一个数字,你可以很容易地与一个常数进行比较

  • 另一种选择,从 2017-11-06 中删除破折号:

    $ echo '2017-01-06' | tr -d '-'
    20170106
    

    同样,输出类似于一个简单的整数

  • 如果您使用的是 Snowflake(您添加了 snowflake-datawarehouse 标签),只需执行

    SELECT SUBSTR(line, -10)::date 
    

    你有一个可以比较的日期

顺便说一句,您提供的详细信息越多,您得到的答案就越好。