2008-09-10 43 views
17

我有一些Ruby代码这需要在格式的命令行日期:的最佳方式

-d 20080101,20080201..20080229,20080301

哪意味着我想运行20080201和20080229(含)之间的所有日期以及列表中的其他日期。

鉴于我可以得到字符串20080201..20080229什么是最好的方式来将其转换为范围的实例。目前我正在使用eval,但感觉应该有更好的方法。

@Purfideas我是寻找一个更通用的答案,将任何类型的int ..int字符串转换为我猜的范围。

回答

14

但后来就去做

ends = '20080201..20080229'.split('..').map{|d| Integer(d)} 
ends[0]..ends[1] 

反正我是不推荐的eval,出于安全原因

+0

什么是涉及使用eval安全原因? – 2008-09-10 08:23:42

+1

cmd行输入是“用户输入”,所以你可以这样总是得到可信任的人执行吗?这是最初的SQL注入...在安全性方面问这个问题......这将是你有史以来的最高分。 :) – Purfideas 2008-09-10 17:15:18

2

假设你要的范围内,通过几个月等正常循环,尽量

require 'date' 

ends = '20080201..20080229'.split('..').map{|d| Date.parse(d)} 
(ends[0]..ends[1]).each do |d| 
    p d.day 
end 
7

注入无参数适用于两个元素阵列:

rng='20080201..20080229'.split('..').inject { |s,e| s.to_i..e.to_i } 

当然,这可以由通用

class Range 
    def self.from_ary(a) 
    a.inject{|s,e| s..e } 
    end 
end 

rng = Range.from_ary('20080201..20080229'.split('..').map{|s| s.to_i}) 
rng.class # => Range 
31
Range.new(*self.split("..").map(&:to_i)) 
0

结合@Purfideas另一个答案在计算器上的某个地方回答,我解决了这个由周围也与输入校验码,所以使用的唯一的事情是一个有效的枚举

if !value[/^[0-9]+\.\.[0-9]+$/].nil? 
    ends = value.split('..').map{|d| Integer(d)} 
    value = ends[0]..ends[1] 
end 

它基本上重写您的字符串值为一个枚举值。如果您在yaml配置文件中添加可枚举字段,这很方便。

如果您的应用程序需要它,您可以使用可选的第三个字面点来扩展正则表达式,这可以是可选的。

0

如果我们不喜欢它

v= "20140101..20150101" 
raise "Error: invalid format: #{v}" if /\d{8}\.\.\d{8}/ !~ v 
r= eval(v) 

和攻击者绕过提高检查(简单地通过操纵运行时关闭异常的方式)的方式,然后我们就可以得到一个危险的eval,这将潜在地破坏宇宙。

因此减少攻击向量的缘故,我们检查格式,然后手工做解析,然后检查结果

v= "20140101..20150101" 
raise "Error: invalid format: #{v}" if /\d{8}\.\.\d{8}/ !~ v 
r= Range.new(*v.split(/\.\./).map(&:to_i)) 
raise "Error: invalid range: #{v}" if r.first> r.last 
1

有这个here的瑰宝。使用正则表达式来验证字符串(没有SQL注入恐惧),然后评估。

0

这里假设您希望将散列存储为系统常量值并将其存储在任何模型中。散列键将是一个范围值。

hash_1 = {1..5 => 'a', 6..12 => 'b', 13..67 => 'c', 68..9999999 => 'd'} 

然后创建系统常量,其值为hash_1.to_json。 .to_json会将您的哈希对象转换为JSON对象。 现在里面的代码创建一个新的哈希hash_2,

JSON.parse(SystemConstant.get('Constant_name')).each{|key,val| temp_k=key.split('..').map{|d| Integer(d)}; hash_2[temp_k[0]..temp_k[1]] = val} 

新hash_2将所需hash_1