简体   繁体   中英

Extract date part from a file path string

I have a string that looks like this: log/archive/2016-12-21.zip , and I need to extract the date part.

So far I have tried these solutions:

1) ["log/archive/2016-12-21.zip"].map{|i|i[/\d{4}-\d{2}-\d{2}/]}.first 
2) "log/archive/2016-12-21.zip".to_date
3) "log/archive/2016-12-21.zip".split("/").last.split(".").first

Is there a better way of doing this?

You can use File.basename passing the extension:

File.basename("log/archive/2016-12-21.zip", ".zip")
# => "2016-12-21"

If you want the value to be a Date , simply use Date.parse to convert the string into a `Date.

require 'date'
Date.parse(File.basename("log/archive/2016-12-21.zip", ".zip"))
require 'date'

def pull_dates(str)
  str.split(/[\/.]/).map { |s| Date.strptime(s, '%Y-%m-%d') rescue nil }.compact
end

pull_dates "log/archive/2016-12-21.zip"
  #=> [#<Date: 2016-12-21 ((2457744j,0s,0n),+0s,2299161j)>]
pull_dates "log/2016-12-21/archive.zip"
  #=> [#<Date: 2016-12-21 ((2457744j,0s,0n),+0s,2299161j)>]
pull_dates "log/2016-12-21/2016-12-22.zip"
  #=> [#<Date: 2016-12-21 ((2457744j,0s,0n),+0s,2299161j)>,
  #    #<Date: 2016-12-22 ((2457745j,0s,0n),+0s,2299161j)>] 
pull_dates "log/2016-12-21/2016-12-32.zip"
  #=> [#<Date: 2016-12-21 ((2457744j,0s,0n),+0s,2299161j)>]
pull_dates "log/archive/2016A-12-21.zip"
  #=> []
pull_dates "log/archive/2016/12/21.zip"
  #=> []

If you just want the date string, rather than the date object, change the method as follows.

def pull_dates(str)
  str.split(/[\/.]/).
      each_with_object([]) { |s,a|
        a << s if (Date.strptime(s, '%Y-%m-%d') rescue nil)}
end

pull_dates "log/archive/2016-12-21.zip"
  #=> ["2016-12-21"] 

This regex should cover most cases. It allows an optional non-digit between year, month and day :

require 'date'

def extract_date(filename)
  if filename =~ /((?:19|20)\d{2})\D?(\d{2})\D?(\d{2})/ then
    year, month, day = $1.to_i, $2.to_i, $3.to_i
    # Do something with year, month, day, or just leave it like this to return an array : [2016, 12, 21]
    # Date.new(year, month, day)
  end
end

p extract_date("log/archive/2016-12-21.zip")
p extract_date("log/archive/2016.12.21.zip")
p extract_date("log/archive/2016:12:21.zip")
p extract_date("log/archive/2016_12_21.zip")
p extract_date("log/archive/20161221.zip")
p extract_date("log/archive/2016/12/21.zip")
p extract_date("log/archive/2016/12/21")
#=> Every example returns [2016, 12, 21]

Please try this

"log/archive/2016-12-21.zip".scan(/\d{4}-\d{2}-\d{2}/).pop
=> "2016-12-21"

If the date format is invalid, it will return nil.

Example:-

"log/archive/20-12-21.zip".scan(/\d{4}-\d{2}-\d{2}/).pop
             ^^
=> nil

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM