Sal-laS
Sal-laS

Reputation: 11639

Extracting numbers from a string

Consider i have a string like this:

"1 hour 7 mins"

I need to extract number of hour (1) and min (7). the problem is either hour or mins can be nill so in this case the string would be 1 hour ot just 7 mins I am mostly interested in regular expression. I have already seen this and run this code

    result = duration.gsub(/[^\d]/, '') 

   result[0]!= nil ? hour=result[0] : hour=0 

   result[1]!=nil ? mins=result[1] : mins=0 

the problem is, when i have only 5 mins it gives me 5 and i do not know it is mins or hour So how can i do it?

Upvotes: 0

Views: 114

Answers (3)

Yule
Yule

Reputation: 9754

I couldn't resist a bit of code golf:

You can do:

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

Explanation:

matches number then 'h', then anything not a number, then number then 'm'. Then gets the match data and does .to_i (which in ruby if it starts with a number uses this number). It then assigns 1st and third match to hours and minutes respectively:

Output:

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 > 

Upvotes: 0

Uelb
Uelb

Reputation: 4093

You could do that :

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

Improved, this is what I wanted :

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

You can try the regex here : http://rubular.com/r/ACwfzUIHBo

Upvotes: 2

Mareq
Mareq

Reputation: 1351

What do you think about something like this:

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

Upvotes: 2

Related Questions