Got more questions? Find advice on: ASP | SQL | XML | Windows
in Search
Welcome to RegexAdvice Sign in | Join | Help

Ascending numbers with specific separators

Last post 02-11-2008, 11:52 AM by ddrudik. 5 replies.
Sort Posts: Previous Next
  •  02-08-2008, 10:24 AM 39417

    Ascending numbers with specific separators

    Hello all,

    I'd like to check on a php page that a text string complies with the following rule : Contain numbers,  in ascending order, with only   ,    or    -     as separators

    The numbers represent requested items (like pages to print), my purpose is then to count the number of item requested.

     1,3,5-6 : Match (4 items)

    1,5,10-12,15,25-30,55 : Match (13 items)

    1,5-4,7 : No Match (not ascending order)

    Any other caracter but 0123456789,-   no match

     

    Thanks.

     

  •  02-08-2008, 10:49 AM 39419 in reply to 39417

    Re: Ascending numbers with specific separators

    I refer you the this article http://regexadvice.com/blogs/mash/archive/2007/06/01/Are-you-ready-for-regex_3F00_.aspx because it seems to me from your question you are under the impression regex do something they don't.  Regexes don't understand context of your data, which is counting numbers.  Aside from testing the allowable characters, your last sentence, everything else in outside the realm of using a regex.

    You could mimic the ascending value but from your samples it would be unrealistic do so for your problem, since to do so you would have to have an upper bound and even that would be unwieldy.


    Michael

    "In theory, theory and practice are the same. In practice, they are not."
    Albert Einstein
  •  02-08-2008, 12:41 PM 39425 in reply to 39417

    Re: Ascending numbers with specific separators

    It requires a bit more than just regex, but this worked for me (note that it finds the first "items" string and then checks if it's valid, if an error is found it returns 0 as the page count).

    If you happen to want to match "items" string that might contain only one number/range you will need to identify what's bordering the "items" string because currently this method requires at least 2 numbers/ranges separated by commas. 

    <?php
    function countpages($string) {
      if (preg_match('/(?:(?:\d+-\d+|\d+),)+(?:\d+-\d+|\d+)/',$string,$result)) {
        $checkone=preg_split('/,|-/',$result[0]);
        for ($h = 0; $h < count($checkone)-1; $h++) {
          if ($checkone[$h]>=$checkone[$h+1]) {
            return 0;
          }
        }
        preg_match_all('/(\d+)-(\d+)/',$result[0],$ranges);
        $count=count($checkone)-(count($ranges[0])*2);
        for ($i = 0; $i < count($ranges[0]); $i++) {
          $count=$count+($ranges[2][$i]-$ranges[1][$i]+1);
        }
        return $count;
      } else {
        return 0;
      }
    }
    echo '<pre>';
    echo '1. pages:'.countpages(' 1,3,5-6 : Match (4 items)').'<br>';
    echo '2. pages:'.countpages('1,5,10-12,15,25-30,55 : Match (13 items)').'<br>';
    echo '3. pages:'.countpages('1,5-4,7 : No Match (not ascending order)').'<br>';
    echo '4. pages:'.countpages('Any other caracter but 0123456789,-   no match').'<br>';
    echo '5. pages:'.countpages(' 3,3-5 : No Match (duplicates)').'<br>';
    ?>

  •  02-11-2008, 3:32 AM 39460 in reply to 39419

    Re: Ascending numbers with specific separators

    Thanks for the help "mash" but It seams my poor english has mislead you regarding my purpose...

    I am not counting on regex to actually count my datas, I would like to use it to check the format of the submitted data before starting to process them since if they are not correct the process might have very bad results.

     

    To "ddrudik" :

    Thanks to you too, that's more the kind of answer I am looking for.

    I think I will manage to work with it in order to achieve my purpose.

  •  02-11-2008, 5:31 AM 39463 in reply to 39425

    Re: Ascending numbers with specific separators

    I think I'm donen with it :

    I added a numeric test in case the string is just a number.

    And also a part so that if there is not comma in the string I check the range.

    Thanks again !

    Here is "final" function :

    countitems($string) {
           
    // Check if string is numeric
            if (is_numeric($string)){ 
            return 1; 
            } 
            // check if numbers are in ascending orders
            $checkorder=preg_split('/,|-/',$string);
            for ($h = 0; $h < count($checkorder)-1; $h++) {
                    if ($checkorder[$h]>=$checkorder[$h+1]) {
                            return 0; 
                    } 
            } 
            // check if range/digit comma range/digit
            if (preg_match('/(?:(?:\d+-\d+|\d+),)+(?:\d+-\d+|\d+)/',$string,$result)) {
                    preg_match_all
    ('/(\d+)-(\d+)/',$result[0],$ranges); 
                    $count
    =count($checkorder)-(count($ranges[0])*2); 
                    for ($i = 0; $i < count($ranges[0]); $i++) { 
                            $count
    =$count+($ranges[2][$i]-$ranges[1][$i]+1); 
                    } 
                    return $count; 
            }
            // check if range
            if (preg_match('/(\d+)-(\d+)/',$string,$result)){ 
                    preg_match_all
    ('/(\d+)-(\d+)/',$result[0],$ranges); 
                    $count
    =count($checkorder)-(count($ranges[0])*2); 
                    for ($i = 0; $i < count($ranges[0]); $i++) { 
                            $count
    =$count+($ranges[2][$i]-$ranges[1][$i]+1); 
                    } 
                    return $count; 
            } 
            // if other case
            return -1;
    }
  •  02-11-2008, 11:52 AM 39478 in reply to 39463

    Re: Ascending numbers with specific separators

    That's quite a bit more complicated than my function, but if that's what you are looking for...


View as RSS news feed in XML