将英语句子转换为ruby键值对的最佳方法是什么?

时间:2015-07-24 23:43:47

标签: ruby

我想转换键值对中的以下句子,如({total_amount:discount_amount})。

$10 off $30 of food #should return {30: 10}
$30 of awesome for $10 #should return {30: 20}
$20 Sneakers for $5 #should return {20: 15}

我该如何处理?这将有所帮助如果我可以得到任何提示开始......

2 个答案:

答案 0 :(得分:2)

我假设每个感兴趣的句子都是这样的:

$XX....for....$YY

或者像这样:

$XX....off....$YY

其中XXYY是非负整数,而"for""off"是关键词,可以告诉您这两个数字要做什么。如果是这样,似乎你想要这个:

arr = ["$10 off $30 of food", "$30 of awesome for $10", "$20 Sneakers for $5"]

让我们首先在扩展模式下定义正则表达式:

r = /
    \$        # match dollar sign
    (\d+)     # match one or more digits in capture group 1
    .*?       # match any number of any character lazily
    \b        # word boundary (so "buzzoff" is not matched)
    (for|off) # match "for" or "off" in capture group 2
    \b        # another word boundary
    .*?       # match any number of any character lazily  
    \$        # match dollar sign
    (\d+)     # match one or more digits in capture group 3
    /x        # extended mode for regex def

arr.each_with_object([]) do |s,a|
  s[r]
  f,l = $1.to_i, $3.to_i
  case $2
  when "for" then a << [f,f-l]
  when "off" then a << [l,f]
  end
end
  #=> [[30, 10], [30, 20], [20, 15]] 

以下是步骤:

enum = arr.each_with_object([])
  #=> #<Enumerator: ["$10 off $30 of food", "$30 of awesome for $10",
  #  "$20 Sneakers for $5"]:each_with_object([])> 

我们可以使用Enumerator#nextenum的每个元素传递给块并将其分配给块变量:

s, a = enum.next
  #=> ["$10 off $30 of food", []] 
s #=> "$10 off $30 of food" 
a #=> []

我们现在执行块计算:

s[r] #=> "10 off $30"

三个捕获组的值为:

$1 #=> "10" 
$2 #=> "off" 
$3 #=> "30" 

因此:

  f,l = $1.to_i, $3.to_i
    #=> [10, 30]

这样:

  case $2
    when "for" then a << [f,f-l]
    when "off" then a << [l,f]
  end

是:

  case "off"
    when "for" then [] << [10, 10-30]
    when "off" then [] << [30, 10]
  end
    #=> [[30, 10]] 

  a #=> [[30, 10]] 

其余的计算也是类似的。

答案 1 :(得分:1)

def read_discount(file_name)
    File.foreach(file_name) do |line|
        /[^\d]*(\d+)[^\d]*(\d+)/ =~ line
        puts "#{$1}:#{$2}" if $1
    end
end

read_discount("31621358.txt")