从字符串中提取数字

时间:2015-11-20 15:39:36

标签: ruby-on-rails regex

考虑我有这样的字符串:

export EDITOR = vi

我需要提取"1 hour 7 mins" (1)和hour(7)的数量。问题是小时或分钟可以min,所以在这种情况下,字符串将是nill,而不仅仅是1 hour 我最感兴趣的是正则表达式。我已经seen this 并运行此代码

7 mins

问题是,当我只有 result = duration.gsub(/[^\d]/, '') result[0]!= nil ? hour=result[0] : hour=0 result[1]!=nil ? mins=result[1] : mins=0 时,它给了我5,我不知道它是5 mins还是mins 那我该怎么办?

3 个答案:

答案 0 :(得分:2)

你可以这样做:

a = duration[/(\d*)(\s*hour)?s?\s*(\d*)(\s*min)?s?/][0]
if a.include?("hour")
  hour = a[0]
  min = a[2]
else
  min = a[0]
end

改进,这就是我想要的:

capture = duration.match(/^((\d*) ?hour)?s? ?((\d*) ?min)?s?/)
hour = capture[2]
min = capture[4]

你可以在这里试试正则表达式: http://rubular.com/r/ACwfzUIHBo

答案 1 :(得分:2)

您如何看待这样的事情:

hours = duration.match(/[\d]* hour/).to_s.gsub(/[^\d]/, '')
minutes = duration.match(/[\d]* mins/).to_s.gsub(/[^\d]/, '')

答案 2 :(得分:0)

我无法抗拒一点代码高尔夫:

你可以这样做:

hours,_,mins = (duration.match /^([\d]* h)?([^\d]*)?([\d]* m)?/)[1..3].map(&:to_i)

说明:

匹配数字然后' h',然后任何不是数字,然后数字然后' m'。然后获取匹配数据,然后执行.to_i(如果以数字开头,则使用此数字)。然后分别将第一和第三场比赛分配给小时和分钟:

输出:

2.2.1 :001 > duration = "5 hours 26 min"
 => "5 hours 26 min" 
2.2.1 :002 > hours,_,mins = (duration.match /^([\d]* h)?([^\d]*)?([\d]* m)?/)[1..3].map(&:to_i)
 => [5, 0, 26] 
2.2.1 :003 > hours
 => 5 
2.2.1 :004 > mins
 => 26 
2.2.1 :005 > duration = "5 hours"
 => "5 hours" 
2.2.1 :006 > hours,_,mins = (duration.match /^([\d]* h)?([^\d]*)?([\d]* m)?/)[1..3].map(&:to_i)
 => [5, 0, 0] 
2.2.1 :007 > duration = "54 mins"
 => "54 mins" 
2.2.1 :008 > hours,_,mins = (duration.match /^([\d]* h)?([^\d]*)?([\d]* m)?/)[1..3].map(&:to_i)
 => [0, 0, 54] 
2.2.1 :009 >