Ruby 从文件路径字符串中提取日期部分

Ruby 从文件路径字符串中提取日期部分,ruby,string,split,Ruby,String,Split,我有一个如下的字符串:log/archive/2016-12-21.zip,我需要提取日期部分 到目前为止,我已经尝试了以下解决方案: 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 有更好的

我有一个如下的字符串:
log/archive/2016-12-21.zip
,我需要提取日期部分

到目前为止,我已经尝试了以下解决方案:

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

有更好的方法吗?

您可以使用
File.basename
传递扩展名:

File.basename("log/archive/2016-12-21.zip", ".zip")
# => "2016-12-21"
如果希望值是
Date
,只需使用
Date.parse
将字符串转换为`Date'

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

您可以使用
File.basename
传递扩展名:

File.basename("log/archive/2016-12-21.zip", ".zip")
# => "2016-12-21"
如果希望值是
Date
,只需使用
Date.parse
将字符串转换为`Date'

require 'date'
Date.parse(File.basename("log/archive/2016-12-21.zip", ".zip"))
需要“日期”
def拉_日期(str)
str.split(/[\/.]/).map{s|Date.strtime(s,'%Y-%m-%d')rescue nil}.compact
结束
拉拽日期“log/archive/2016-12-21.zip”
#=> [#]
拉拽日期“log/2016-12-21/archive.zip”
#=> [#]
拉拽日期“log/2016-12-21/2016-12-22.zip”
#=> [#,
#    #] 
拉拽日期“log/2016-12-21/2016-12-32.zip”
#=> [#]
拉拽日期“log/archive/2016A-12-21.zip”
#=> []
拉拽日期“log/archive/2016/12/21.zip”
#=> []
如果只需要日期字符串而不是日期对象,请按如下所示更改方法

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"] 
def pull_日期(str)
str.split(/[\/.]/)。
每个带有_对象([]){| s的_,一个|
a[“2016-12-21”]
需要“日期”
def拉_日期(str)
str.split(/[\/.]/).map{s|Date.strtime(s,'%Y-%m-%d')rescue nil}.compact
结束
拉拽日期“log/archive/2016-12-21.zip”
#=> [#]
拉拽日期“log/2016-12-21/archive.zip”
#=> [#]
拉拽日期“log/2016-12-21/2016-12-22.zip”
#=> [#,
#    #] 
拉拽日期“log/2016-12-21/2016-12-32.zip”
#=> [#]
拉拽日期“log/archive/2016A-12-21.zip”
#=> []
拉拽日期“log/archive/2016/12/21.zip”
#=> []
如果只需要日期字符串而不是日期对象,请按如下所示更改方法

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"] 
def pull_日期(str)
str.split(/[\/.]/)。
每个带有_对象([]){| s的_,一个|
a[“2016-12-21”]
请试试这个

"log/archive/2016-12-21.zip".scan(/\d{4}-\d{2}-\d{2}/).pop
=> "2016-12-21"
如果日期格式无效,它将返回nil

例如:-

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

请试试这个

"log/archive/2016-12-21.zip".scan(/\d{4}-\d{2}-\d{2}/).pop
=> "2016-12-21"
如果日期格式无效,它将返回nil

例如:-

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

希望有帮助。

此正则表达式应涵盖大多数情况。它允许在年、月和日之间选择非数字:

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]

此正则表达式应涵盖大多数情况。它允许在年、月和日之间选择非数字:

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]

如果点总是最后才出现,那么你可以试试这个
“log/archive/2016-12-21.zip”。split(/[\/.]/)[-2]
是的,点总是最后出现,即使这不是最简单的解决方案,我还是会使用正则表达式(\/(\d{4}-\d{2}-\d{2})\.zip)。原因是,您可以使用匹配项对其进行测试,并且您肯定会检测到字符串的结构是否发生了变化。我不知道数字2的行为如何,但我不会选择数字3,因为它可以评估字符串,而完全没有日期……如果点始终只出现在最后,那么您可以尝试此
“log/archive/2016-12-21.zip”.split(/[\/.]/)[-2]
是的,即使不是最简单的解决方案,我还是会使用正则表达式(\/(\d{4}-\d{2}-\d{2})\.zip)。原因是,您可以使用匹配项进行测试,您肯定会检测到字符串的结构是否发生变化。我不知道数字2的行为如何,但我不会选择数字3,因为它可以计算字符串,而不需要任何日期…如果字符串来自目录读取,这将是一个非常好的解决方案。但我的问题不在terest,如果文件名中没有有效日期会发生什么?例如“log/archive/12-21.zip”@DoktorOSwaldo在这种情况下,不是直接将值传递给
Date。parse
你将不得不自己处理解析并编写一个日期。是的,但是你知道ruby在这种情况下的行为吗,它会失败并给出一个异常吗?还是类似于1970-12-21?可以肯定,该日期的格式总是正确的irst:
File.basename
作用于一个字符串-该字符串是否由另一个
文件
操作生成并不重要。因此,字符串是否从目录读取中获得并不重要-字符串的格式才是相关的如果字符串是从目录读取的,这将是一个非常好的解决方案。但是出于兴趣,我的问题是,如果文件名中没有有效日期,会发生什么?例如“log/archive/12-21.zip”@DoktorOSwaldo在这种情况下,不是直接将值传递到
Date.parse
您必须自己处理解析并编写日期。但是您知道ruby在这种情况下的行为吗,它会失败并给出异常吗?或者它会是1970-12-21之类的吗?它肯定日期将以正确的格式始终保持在alwaysF中irst:
File.basename
作用于一个字符串-该字符串是否由另一个
文件
操作生成并不重要。因此,字符串是否从目录读取中获得无关紧要-相关的是字符串的格式