Regex to match time ranges involving am/pm like 7am-10pm -
i have written following regex
(1[012]|[1-9])(am|pm)\-(1[012]|[1-9])(am|pm)
to match following kind of time formats:
7am-10pm (matches correctly , creates 4 match groups 7, am, 10, pm) 13am-10pm (this should not matched, matches , creates 4 match groups 3, am, 10, pm) 10pm (this doesn't match expected because doesn't specify time range end) 111am-10pm (this should not matched, matches , creates 4 match groups 11, am, 10, pm)
how can improve regex such don't need repeat digits , am/pm pattern , following things:
it captures time range components in 7am-10am there should 2 match groups 7am, 10am.
it matches proper hours e.g. 111am or 13pm etc should considered no-match.
i don't know if possible regex can make regex match correct time ranges e.g. 7am-1pm should match, 4pm-1pm should considered no match?
note: using ruby 2.2.1
thanks.
first let's see did wrong :
13am-10pm (this should not matched, matches , creates 4 match groups 3, am, 10, pm)
it matches proper hours e.g. 111am or 13pm etc should considered no-match.
this matches, since allow match single digit [1-9] here : (1[012]|[1-9]).
in order fix this, should either allow 1 [1-9] digit, or 1 + [0-2]. since not know when regex starts 'll use word boundary sure have "word start".
since not want capture numbers whole time plus am|pm can use non capturing group :
\b((?:1[0-2]|[1-9])
then it's matter of repeating ourselves , adding dash :
\b((?:1[0-2]|[1-9])[ap]m)-((?:1[0-2]|[1-9])[ap]m)
regarding point 3. well, yes could regex, better off adding logical check once group 1 , 2 see if time range makes sense.
all in :
# \b((?:1[0-2]|[1-9])[ap]m)-((?:1[0-2]|[1-9])[ap]m) # # # assert position @ word boundary «\b» # match regular expression below , capture match backreference number 1 «((?:1[0-2]|[1-9])[ap]m)» # match regular expression below «(?:1[0-2]|[1-9])» # match either regular expression below (attempting next alternative if 1 fails) «1[0-2]» # match character “1” literally «1» # match single character in range between “0” , “2” «[0-2]» # or match regular expression number 2 below (the entire group fails if 1 fails match) «[1-9]» # match single character in range between “1” , “9” «[1-9]» # match single character present in list “ap” «[ap]» # match character “m” literally «m» # match character “-” literally «-» # match regular expression below , capture match backreference number 2 «((?:1[0-2]|[1-9])[ap]m)» # match regular expression below «(?:1[0-2]|[1-9])» # match either regular expression below (attempting next alternative if 1 fails) «1[0-2]» # match character “1” literally «1» # match single character in range between “0” , “2” «[0-2]» # or match regular expression number 2 below (the entire group fails if 1 fails match) «[1-9]» # match single character in range between “1” , “9” «[1-9]» # match single character present in list “ap” «[ap]» # match character “m” literally «m»
Comments
Post a Comment