#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2003
    Location
    Texas
    Posts
    171
    Rep Power
    28

    Limiting number of digits


    In my efforts to validate user input, I've been using regular expressions to test if a number is a decimal.

    Since I'm pretty ignorant when it comes to creating my own, I was able to find this one:

    http://regexlib.com/REDetails.aspx?regexp_id=54
    Code:
    ^[-+]?\d*\.?\d*$
    Which, per the description:
    Matches any floating point numer/numeric string, including optional sign character (+ or -). Also matches empty strings.

    It works quite well, but I was looking to make a (seemgingly) trivial change. I would like to limit the amount of numbers after the decimal, but I'm unsure as to how I might go about?

    Say, for example, if I wanted to match only 1 digit after the decimal, or 2 digits.

    I appreciate any help.
  2. #2
  3. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,692
    Rep Power
    6351
    \d* means "zero or more digits". The asterisk is the "quantifier." The built-in quantifiers are:
    ? - zero or one (also called the optional quantifier)
    * - zero or more
    + - one or more

    You can also define your own quantifiers, using curly braces:
    \d{0,45} is "up to 45 digits"
    \d{3,6} is "between 3 and 6, inclusive"

    I'm sure you can figure it out from there.

    -Dan
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2003
    Location
    Texas
    Posts
    171
    Rep Power
    28
    Thanks, Dan.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2003
    Location
    Texas
    Posts
    171
    Rep Power
    28
    Well, I apparently didn't quite understand what was happening because I have encountered another question with this expression.

    I'm trying the following:

    Code:
    ^-?\d{0,6}\.?\d{0,2}$
    ...in the hopes that it will match only up to 6 digits before the decimal. Of course, I'm doing something wrong, but having trouble figuring it out.

    For testing, I've been using...
    A Better .NET Regular Expression Tester

    ...to attempt to figure this out, but with little luck.

    It appears that something like...

    Code:
    ^-?\d?\d?\d?\d?\d?\d?.?\d{0,2}$
    will achieve the desired results, but surely there's a more elegant way.

    Any ideas?
    Last edited by jdavis; December 9th, 2009 at 04:40 PM.
  8. #5
  9. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,692
    Rep Power
    6351
    In order to ensure programmers never get any sleep or do anything of value, each regular expression engine handles things differently. For instance, I know for a fact O'Reilly's "Web Database Applications with MySQL & PHP" has a regexp chapter that recommends you do things that will throw parse errors in PHP. That's just the way things are.

    To address your actual concern, you were absolutely right in writing that regular expression, provided you were going to put it into Perl, Grep, or PHP. Since you're using .NET, you'll have to look up how your particular language's regular expression parser handles quantifiers. This is as far as I can take you, traveler.

    -Dan
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2003
    Location
    Texas
    Posts
    171
    Rep Power
    28
    Thanks Dan, I appreciate it.

    I'm begininng to think I should just go about this a different way entirely.
  12. #7
  13. kill 9, $$;
    Devshed Supreme Being (6500+ posts)

    Join Date
    Sep 2001
    Location
    Shanghai, An tSín
    Posts
    6,897
    Rep Power
    3886
    Originally Posted by jdavis
    For testing, I've been using...
    A Better .NET Regular Expression Tester

    ...to attempt to figure this out, but with little luck.
    Could you also post the "source" text that you're running the regexp on, along with the results you're expecting?
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2003
    Location
    Texas
    Posts
    171
    Rep Power
    28
    Originally Posted by ishnid
    Could you also post the "source" text that you're running the regexp on, along with the results you're expecting?
    Surely.

    I'm validating some values, and for this particular field it is acceptable to have integer values up to 6 digits, but if there's a decimal following the 6th digit then they're allowed 2 decimal places.

    So, the following numbers would be valid:

    empty
    123
    123456
    123456.
    123456.7
    123456.78

    The following would be invalid:
    1234567 (exceeds a 6 digit number)
    123456.123 (exceeds 2 digit precision)

    Unfortuantely, in my efforts I wasn't even able to make a simple regex that matches just one set of 6 digits.

    My biggest problem appears to be that I can't figure out how to match only up to 6 digits before the optional decimal.

    I sincerely appreciate any help.
    Last edited by jdavis; December 10th, 2009 at 09:03 AM.
  16. #9
  17. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,692
    Rep Power
    6351
    I had to alter your expression a BIT, but this works in PHP:
    PHP Code:
    $check = array(
    "",
    "123",
    "123456",
    "123456.",
    "-1234",
    "-12345.67",
    "123456.7",
    "123456.78",
    "1234567",
    "123456.123");
    foreach ( 
    $check as $number ) {
        if ( 
    preg_match("/^-?\d{0,6}(\.\d{0,2})?$/"$number) ) {
            echo 
    "{$number} is valid.<br />\n";
        } else {
            echo 
    "{$number} is INVALID.<br />\n";
        }

    Outputs:
    Code:
    is valid.
    123 is valid.
    123456 is valid.
    123456. is valid.
    -1234 is valid.
    -12345.67 is valid.
    123456.7 is valid.
    123456.78 is valid.
    1234567 is INVALID.
    123456.123 is INVALID.
    It wasn't working as you expected because the decimal was optional. A string of seven characters was matching the first six, not finding a decimal (which was ok), then matching another digit. By making the "decimal, then zero to two digits" an optional block by itself, it demanded the presence of a decimal if the last two digits were going to be counted.

    -Dan

    Comments on this post

    • jdavis agrees : Much appreciated.
    • ishnid agrees : Exactly
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2003
    Location
    Texas
    Posts
    171
    Rep Power
    28
    That's tremendous, Dan. They're going to write songs about you one day.

    Thanks!

    On a side note, I've been reading about a tool called RegexBuddy that is particularly helpful and explanatory when building expressions. I think I may pick that up as well.

    Thanks again.
  20. #11
  21. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,692
    Rep Power
    6351
    Regexp buddy is great, I recommend it. I don't actually USE it, of course, but some of the guys around the office do, and it's made them stop asking me for help, so that right there is a recommendation for the product.

    -Dan
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.

IMN logo majestic logo threadwatch logo seochat tools logo