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:

  1. it captures time range components in 7am-10am there should 2 match groups 7am, 10am.

  2. it matches proper hours e.g. 111am or 13pm etc should considered no-match.

  3. 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

Popular posts from this blog

css - SVG using textPath a symbol not rendering in Firefox -

Java 8 + Maven Javadoc plugin: Error fetching URL -

order - Notification for user in user account opencart -