# Regular expresson isue

**URL:** <https://www.ruby-forum.com/t/regular-expresson-isue/145702>\
**Category:** Ruby\
**Created:** [August 13, 2008, 3:34am UTC](https://www.ruby-forum.com/t/regular-expresson-isue/145702 "2008-08-13T03:34:19Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [August 13, 2008, 3:34am UTC](https://www.ruby-forum.com/t/regular-expresson-isue/145702/1 "2008-08-13T03:34:19Z")

</div>

I have following regular expression to parse time.

([0-9]|0[0-9]|1[012]):([0-9]|0[0-9]|[1-5][0-9])\s\*(am|pm)

I don’t want this regext to match 13:45 PM because the the numerical  
value before the colon should be limited to 12. How to fix it?

You can play with this regex at

[http://www.rubular.com/regexes/863](http://www.rubular.com/regexes/863)

---

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [August 13, 2008, 3:38am UTC](https://www.ruby-forum.com/t/regular-expresson-isue/145702/2 "2008-08-13T03:38:20Z")

</div>

Raj S. wrote:

> I have following regular expression to parse time.
> 
> ([0-9]|0[0-9]|1[012]):([0-9]|0[0-9]|[1-5][0-9])\s\*(am|pm)

You want to match from the beginning of the string. So put a ^ before  
your statement -

^([0-9]|0[0-9]|1[012]):([0-9]|0[0-9]|[1-5][0-9])\s\*(am|pm)

---

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [August 13, 2008, 4:43am UTC](https://www.ruby-forum.com/t/regular-expresson-isue/145702/3 "2008-08-13T04:43:41Z")

</div>

From: Raj S. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]

# ([0-9]|0[0-9]|1[012]):([0-9]|0[0-9]|[1-5][0-9])\s\*(am|pm)

# I don’t want this regext to match 13:45 PM because the the numerical

# value before the colon should be limited to 12. How to fix it?

Hi Raj,

the 13 is matching

([0-9]|0[0-9]|1[012])  
^^^^^  
this

because the regex will match the 3. the regex did not care if it had a 1  
before it.

You may want to tell it to not match any preceding digit (or else it be  
a beginning of the string) if you want a stand alone digit.  
eg, you may want to achor/prefix it w the ^ (for beginning of string)  
or \D (to represent a non-digit character)

sample tests,

irb(main):112:0\> re = /((^|\D)[0-9]|0[0-9]|1[012])😕  
=\> /((^|\D)[0-9]|0[0-9]|1[012])😕

irb(main):113:0\> re =~ “1:”  
=\> 0  
irb(main):114:0\> re =~ " 1:"  
=\> 0  
irb(main):117:0\> re =~ “13:”  
=\> nil

irb(main):122:0\> re =~ “01:”  
=\> 0  
irb(main):123:0\> re =~ “11:”  
=\> 0  
irb(main):124:0\> re =~ “12:”  
=\> 0

kind regards -botp

---

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [August 13, 2008, 10:18am UTC](https://www.ruby-forum.com/t/regular-expresson-isue/145702/4 "2008-08-13T10:18:02Z")

</div>

Sorry to be the awkward one, but maybe you should consider handling  
this programatically, rather than in a regex?

Pros: your code is likely to be easier to understand: that makes it  
more maintainable.  
Cons: your code will be longer.

---

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [August 13, 2008, 11:43am UTC](https://www.ruby-forum.com/t/regular-expresson-isue/145702/5 "2008-08-13T11:43:40Z")

</div>

2008/8/13 Raj S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> I have following regular expression to parse time.
> 
> ([0-9]|0[0-9]|1[012]):([0-9]|0[0-9]|[1-5][0-9])\s\*(am|pm)

This seems overly complex, especially your minute matching. This can  
be simplified at least to “\d?\d” or “\d{1,2}”.

> I don’t want this regext to match 13:45 PM because the the numerical  
> value before the colon should be limited to 12. How to fix it?

Do you need this for direct matching of a string or scanning of larger  
volumes of text? Here’s an alternative (untested):

%r{  
\b  
(0?\d|1[012]) # hour  
:  
([0-5]\d) # minute  
\s\*  
(am|pm)  
}xi

If you want to use this for matching you probably rather want

%r{  
\A  
(0?\d|1[012]) # hour  
:  
([0-5]\d) # minute  
\s\*  
(am|pm)  
\z  
}xi

Note, the comments can stay in there when copy and pasting.

Kind regards

robert
