Ruby库可将字符串解析为Google表格样式的适当数据类型

时间:2019-05-25 15:25:05

标签: ruby parsing

我想将Ruby字符串解析为它表示的数据类型,就像Google表格执行此操作一样。

例如,当您在Google表格中键入“ hello”时,它将被解释为字符串。 “ 100”作为数字,“ $ 100”作为货币,等等。

更多示例:

  • 字符串“ 2001年1月1日”应转换为日期。

  • 字符串“ true”应转换为布尔值。

无需手动编写正则表达式驱动的case语句来完成此操作的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

必须指定可能的日期格式。如果使用Date#parse,则字符串"Theresa May has announced she will resign"将返回#<Date: 2019-05-01 ((2458605j,0s,0n),+0s,2299161j)>

这是一个开始。

require 'date'
require 'bigdecimal'

def my_class(str)
  return true if str == 'true'
  return false if str == 'false'
  return nil if str == 'nil'
  date = DateTime.strptime(str, '%b %d, %Y') rescue nil
  return date unless date.nil?
  return BigDecimal(str) if str.match?(/\A-?0.\d+e\d+\z/i)
  n = Float(str) rescue nil
  return n if n && str.include?('.')
  n = Integer(str) rescue nil
  return n unless n.nil?
  raise ArgumentError
end

my_class 'true'    #=> true 
my_class 'false'   #=> true 
my_class 'nil'     #=> nil 
my_class '-32'     #=> -32 
my_class '0'       #=> 0
my_class '1.0'     #=> 1.0 
my_class '-1.03'   #=> -1.03 
my_class '1.02e-2' #=> 0.0102
my_class '-1.99E2' #=> -199.0
my_class '-0.99e1' #=> -0.99e1 (BigDecimal)
my_class '-0.99E1' #=> -0.99e1 (BigDecimal)
my_class '0.0'     #=> 0.0
my_class 'Jan 1, 2001'
  #=> #<DateTime: 2001-01-01T00:00:00+00:00 ((2451911j,0s,0n),+0s,2299161j)> 
my_class 'January 1, 2001'
  #=> #<DateTime: 2001-01-01T00:00:00+00:00 ((2451911j,0s,0n),+0s,2299161j)> 
my_class 'January 32, 2001'
  #=> nil 

str = "0.0"之外,将字符串的返回值转换为BigDecimal,然后再将其转换回与模式匹配的字符串

r = /\A-?0\.\d+e\d+\z/

(例如BigDecimal("123.4").to_s #=> "0.1234e3")。相比之下,用科学计数法表示浮点数的字符串通常会匹配模式

/\A-?[1-9]\.\d+e\d+\z/

因此,我假设只有当字符串与BigDecimal匹配时,字符串才与r匹配(尽管我使r的大小写无关,例如,{{1 }}将被视为"0.12E2"