CodeIgniter Forums
Strange regex behaviour - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forum-20.html)
+--- Forum: Archived Development & Programming (https://forum.codeigniter.com/forum-23.html)
+--- Thread: Strange regex behaviour (/thread-23288.html)



Strange regex behaviour - El Forum - 10-06-2009

[eluser]alboyd[/eluser]
Hi Guys,

I have no idea about regex really - never really tried to figure it out too much. I can guess how the regex below is supposed to work and I think I found this snippet online somewhere.

All along so far I have been testing with a time of 20:30 and it has worked but I have just found out that other valid HH:MM times are not working?

Here is some testing code I am running.
Code:
function index()
    {
        echo '01:50' . "<br>";
        $this->valid_time('01:50');
        
        echo "<br>";
        echo '03:45' . "<br>";
        $this->valid_time('03:45');
        
        echo "<br>";
        echo '05:40' . "<br>";
        $this->valid_time('05:40');
        
        echo "<br>";
        echo '07:35' . "<br>";
        $this->valid_time('07:35');
        
        echo "<br>";
        echo '09:30' . "<br>";
        $this->valid_time('09:30');
        
        echo "<br>";
        echo '11:25' . "<br>";
        $this->valid_time('11:25');
        
        echo "<br>";
        echo '18:55' . "<br>";
        $this->valid_time('18:55');
        
        echo "<br>";
        echo '20:55' . "<br>";
        $this->valid_time('20:55');
        die();
        
        //$this->admin_panel();
    }
    
    function valid_time($str) {
            
        if (ereg("([0-23]{2}):([0-59]{2})", $str)) {
            $arr = split(":", $str);
            $hh = $arr[0];
            $mm = $arr[1];
            echo 'regex is fine';
            if (is_numeric($hh) && is_numeric($mm)) {
               return true;
            } else {
                return false;
            }
        } else {
            echo 'regex fails';
            return false;
        }
    }

Here are the results:

Code:
01:50
regex is fine
03:45
regex is fine
05:40
regex fails
07:35
regex fails
09:30
regex fails
11:25
regex is fine
18:55
regex fails
20:55
regex is fine

Anyone got an idea of what is wrong - or does anyone know how I can validate a time is HH:MM.

Thanks!


Strange regex behaviour - El Forum - 10-06-2009

[eluser]alboyd[/eluser]
I've found this regex online and it seems to work.

Code:
^(([0-1][0-9])|([2][0-3]))[:]([0-5][0-9])$

I'd still be interested in ideas of why the original was not working consistently?


Strange regex behaviour - El Forum - 10-06-2009

[eluser]aquariuz[/eluser]
[0-23] means: 0 to 2, plus 3. So basically it means 0 to 3.
As soon as a 4 or higher appears in the first segment, the regular expression fails.


Strange regex behaviour - El Forum - 10-06-2009

[eluser]Phil Sturgeon[/eluser]
Actually I believe it is a 05 != 5 problem.

Also, I would switch to using preg as ereg is slowly being depreciated. It will start flagging errors in PHP 6.


Strange regex behaviour - El Forum - 10-06-2009

[eluser]BrianDHall[/eluser]
[quote author="aquariuz" date="1254845365"][0-23] means: 0 to 2, plus 3. So basically it means 0 to 3.
As soon as a 4 or higher appears in the first segment, the regular expression fails.[/quote]

Just wanted to confirm this as correct and elucidate.

Regex works on characters individually - to a regex there is no number greater than 9. 90 is not bigger than 9, because it is actually just a 9 and a 0 that happen to be next to each other.

To get a number less than one-hundred you might try, for instance "/[0-9][0-9]/" - but again it will not behave as expected as it will match the 1 and the 0 of the number 100.

A good site for regex as a reference: http://www.regular-expressions.info/


Strange regex behaviour - El Forum - 10-06-2009

[eluser]sophistry[/eluser]
you could shorten the new regex by taking out a few brackets and a redundant dash... also, definitely use the preg_ functions over ereg_ functions.

from:
Code:
^(([0-1][0-9])|([2][0-3]))[:]([0-5][0-9])$

to:
Code:
^(([01][0-9])|(2[0-3]))\:([0-5][0-9])$