Home > Mobile >  Regex for certain string and digit for time
Regex for certain string and digit for time

Time:12-08

anyone can help me? I have a string with format: 10 mins - 20 mins OR 1 min - 10 mins OR 10 mins - 1 hour OR 10 mins - 1 hour 30 mins OR 10 mins - 2 hours OR 10 mins - 2 hours 30 mins. I wanna create a regex for all formats but I can't :disappointed: . Please help me, thanks a lot.

A regex possible with all above formats.

CodePudding user response:

I might split on the dash first, then match out the components in each side using the same regular expression.

E.g.

"1 hour 10 mins - 3 hours".split(/\s -\s /, 2).map do |s| 
  s.scan(
    /
        \d  \s  mins
      | \d  \s  hour(?=s?)
      | \d  \s  hour(?=s?) 
        \s  
        \d  \s  min(?=s?)
    /x
  ) 
end
# => [["1 hour", "10 mins"], ["3 hour"]]

"1 hour 10 mins - 40 mins".split(/\s -\s /, 2).map do |s| 
  s.scan(
    /
        \d  \s  mins
      | \d  \s  hour(?=s?)
      | \d  \s  hour(?=s?) 
        \s  
        \d  \s  min(?=s?)
    /x
  ) 
end
# [["1 hour", "10 mins"], ["40 mins"]]

CodePudding user response:

I've assumed:

  • every string contains only minutes (not hours) to the left of the minus sign; and
  • hours, where present, are between 1 and 9.

One can then use String#match and MatchData#named_captures with the regular expression

rgx = /(?<lmin>(?:[1-9]|[1-5]\d)) mins? \- (?:(?<hr>[1-9]) hours?(?: (?<rminwhr>\g<lmin>) mins?)?|(?<rminwohr>\g<lmin>) mins?)/

to extract the values of interest. Let's try it for the examples given in the question.

["10 mins - 20 mins",
 "1 min - 10 mins",
 "10 mins - 1 hour",
 "10 mins - 1 hour 30 mins",
 "10 mins - 2 hours",
 "10 mins - 2 hours 30 mins"].each do |str|
   m = str.match(rgx)
   puts str
   puts "str.match(rgx) = #{m}"
   puts "captures = #{m.named_captures}"
   puts
 end

displays the following.

10 mins - 20 mins
str.match(rgx) = 10 mins - 20 mins
captures = {"lmin"=>"20", "hr"=>nil, "rminwhr"=>nil, "rminwohr"=>"20"}

1 min - 10 mins
str.match(rgx) = 1 min - 10 mins
captures = {"lmin"=>"10", "hr"=>nil, "rminwhr"=>nil, "rminwohr"=>"10"}

10 mins - 1 hour
str.match(rgx) = 10 mins - 1 hour
captures = {"lmin"=>"10", "hr"=>"1", "rminwhr"=>nil, "rminwohr"=>nil}

10 mins - 1 hour 30 mins
str.match(rgx) = 10 mins - 1 hour 30 mins
captures = {"lmin"=>"30", "hr"=>"1", "rminwhr"=>"30", "rminwohr"=>nil}

10 mins - 2 hours
str.match(rgx) = 10 mins - 2 hours
captures = {"lmin"=>"10", "hr"=>"2", "rminwhr"=>nil, "rminwohr"=>nil}

10 mins - 2 hours 30 mins
str.match(rgx) = 10 mins - 2 hours 30 mins
captures = {"lmin"=>"30", "hr"=>"2", "rminwhr"=>"30", "rminwohr"=>nil}

One can see a demonstration of the regular expression here. Hover the cursor over the regular expression to see an explanation of the function of each part of the expression. These results are shown for the PCRE regex engine but they are the same for Ruby's regex engine (Oniguruma).

  • Related