2

我有一个 UNIX ls 输出,必须编写一个正则表达式来返回大于 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-1159 /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-1159 /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

4

3 回答 3

1

为了返回以晚于 2017 年 11 月 5 日的日期结束的整行,您可以使用此正则表达式

^.*=(?: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

于 2018-02-20T18:20:52.393 回答
1

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

请注意,这不是日期验证
这只是一个大于日期的验证。 验证日期
需要更多的正则表达式(包括闰年) 。
但是,我不认为这是你需要的。

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

于 2018-02-20T18:42:36.550 回答
0

通过尝试使用正则表达式,您对自己来说太难了。不确定您使用的是什么工具,但我确信还有其他选择:

  • 如果它类似于 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 
    

    你有一个可以比较的日期

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

于 2018-02-22T21:31:45.547 回答