根据是否有效日期映射字母和数字的字符串

时间:2017-04-01 07:55:20

标签: ruby gsub

我有5个字符串:

MO170915C00075000

GILD1514H117

9ZZZFD898

AHMIQ

894990415

前两个在第一组数字之间有有效日期,然后是下一个单一字母(例如:C)。

如果我可能会问,如何选择前两个字符串,因为它们中的日期(需要确定它们包含第一组字母之后和单个字符之前的日期)然后正确格式化日期?

对于第一个,我可以使用下面的GSub获取日期:

("20" + @ticker.gsub(/(\w+?)(\d{6})([a-z])\d+/i,'\2')).to_date

2 个答案:

答案 0 :(得分:3)

您可以使用Date._parse查看Date.parse可以找到哪些信息。

没有任何规格,你将基本上在黑暗中拍摄。由于逻辑是如此模糊,它不能用任何奇怪的字符串作为输入神奇地工作:

[
    {
        "customer_name": "John",
        "order_id": 1,
        "items": [
            { "id": 4, "quantity": 1 },
            { "id": 24, "quantity": 4 },
            { "id": 16, "quantity": 1 },
         ]
    },
......

输出:

require 'date'
weird_dates = %w(MO170915C00075000 MA20172115C00075000 GILD1514H117 9ZZZFD898 AHMIQ 894990415)

weird_dates.each do |date_str|
  date_hash = Date._parse(date_str)
  puts date_str
  puts "  #{date_hash}"
  if date_hash[:year] && date_hash[:mon] && date_hash[:mday]
    print "  It looks like a date"
    begin
      date = Date.parse(date_str)
      puts " : #{date}"
    rescue ArgumentError
      puts " but it's not a valid one!"
    end
  else
    puts "  Sorry, not enough information"
  end
  puts
end

如果您知道确切的输入格式,则应使用Date.strptime

答案 1 :(得分:0)

<强>代码

require 'date'

def extract_dates(arr)
  arr.each_with_object([]) do |str,a|
    s = str[/\d+/] || ''
    a <<
    case s.size
    when 8
      [convert_to_time(s, 4, 2, 2)]
    when 7
      [convert_to_time(s, 4, 2, 1), convert_to_time(s, 4, 1, 2)]
    when 6
      [convert_to_time(s, 4, 1, 1), convert_to_time(s, 2, 2, 2)]
    when 5
      [convert_to_time(s, 2, 2, 1), convert_to_time(s, 2, 1, 2)]
    when 4
      [convert_to_time(s, 2, 1, 1)]
    else
      []
    end.compact
  end
end

def convert_to_time(s, y, m, d)
  ss = s.dup
  ss.insert(0, "20") if y == 2
  ss.insert(4, "0") if m == 1
  ss.insert(6, "0") if d == 1
  DateTime.strptime(ss, "%Y%m%d") rescue nil
end

<强>实施例

arr = <<-_.split
MA170915C00075000
MA20170915C00075000
MA20172115C00075000
GILD1514H117
GILD15111H117
9ZZZFD898
AHMIQ
894990415
_
  #=> ["MA170915C00075000", "MA20170915C00075000", "MA20172115C00075000",
  #    "GILD1514H117", "GILD15111H117", "9ZZZFD898", "AHMIQ", "894990415"] 

arr.zip(extract_dates arr)
  #=> [["MA170915C00075000",
  #      [#<DateTime: 1709-01-05T00:00:00+00:00 ((2345264j,0s,0n),+0s,2299161j)>,
  #       #<DateTime: 2017-09-15T00:00:00+00:00 ((2458012j,0s,0n),+0s,2299161j)>]],
  #    ["MA20170915C00075000",
  #      [#<DateTime: 2017-09-15T00:00:00+00:00 ((2458012j,0s,0n),+0s,2299161j)>]],
  #    ["MA20172115C00075000", []],
  #    ["GILD1514H117",
  #      [#<DateTime: 2015-01-04T00:00:00+00:00 ((2457027j,0s,0n),+0s,2299161j)>]],
  #    ["GILD15111H117",
  #      [#<DateTime: 2015-11-01T00:00:00+00:00 ((2457328j,0s,0n),+0s,2299161j)>,
  #       #<DateTime: 2015-01-11T00:00:00+00:00 ((2457034j,0s,0n),+0s,2299161j)>]],
  #    ["9ZZZFD898", []],
  #    ["AHMIQ", []],
  #    ["894990415", []]] 

这表明:

  • “MA170915C00075000”,“170915”中的第一个数字串,可以解释为两个日期之一,“1709-1-5”和“2017-09-15”。
  • “MA20170915C00075000”,“20170915”中的第一个数字,只能解释为一个日期,“2017-09-15”。
  • “MA20172115C00075000”,“20172115”中的第一个数字,不代表有效日期,因此返回一个空数组。
  • “GILD15111H117”,“15111”中的第一个数字可代表日期“2015-11-01”或“2015-01-11”。