如何在Ruby中使用格式化的掩码从字符串中提取值

时间:2019-07-14 14:17:01

标签: ruby

我们可以使用Ruby:"I have %{amount} %{food}" % {amount: 5, food: 'apples'}来获得“我有5个苹果”。反变换是否有通用的方法:使用“我有5个苹果”和“我有%{amount}%{food}”来获得{amount: 5, food: 'apples'}

2 个答案:

答案 0 :(得分:2)

def doit(s1, s2)
  a1 = s1.split 
  a2 = s2.split
  a2.each_index.with_object({}) do |i,h|
    word = a2[i][/(?<=%\{).+(?=\})/]
    h[word.to_sym] = a1[i] unless word.nil?
  end.transform_values { |s| s.match?(/\A\-?\d+\z/) ? s.to_i : s }
end

s1 = "I have 5 apples"
s2 = "I have %{amount} %{food}"
doit(s1, s2)
  #=> {:amount=>5, :food=>"apples"} 

s1 = "223 parcels were delivered last month"
s2 = "%{number} parcels were %{action} last %{period}"
doit(s1, s2)
  #=> {:number=>223, :action=>"delivered", :period=>"month"}

正则表达式读取“匹配一个或多个字符(.+),并紧跟"%{"(?<=%\{)正向后注)并立即然后是"}"(?=\})正向超前)。

答案 1 :(得分:0)

如果子字符串用空格分隔,则可以使用named captures找到相应的正则表达式:

text = "I have 5 apples"
# "I have %{amount} %{food}"
format = /\AI have (?<amount>\S+) (?<food>\S+)\z/

p text.match(format).named_captures
# {"amount"=>"5", "food"=>"apples"}

您没有显示任何代码,因此我将其保留为将"I have %{amount} %{food}"字符串转换为/\AI have (?<amount>\S+) (?<food>\S+)\z/正则表达式的练习。