Forums: » Register « |  Free Tools |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support |

New Free Tools on Dev Shed!

#1
December 2nd, 2009, 12:39 PM
 jdavis
Contributing User

Join Date: Jan 2003
Location: Texas
Posts: 171
Time spent in forums: 2 Days 20 h 3 m 24 sec
Reputation Power: 27
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
December 3rd, 2009, 04:02 PM
 ManiacDan
Sarcky

Join Date: Oct 2006
Location: Pennsylvania, USA
Posts: 10,499
Time spent in forums: 2 Months 3 Weeks 5 Days 8 h 34 m 4 sec
Reputation Power: 6300
\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

#3
December 7th, 2009, 09:41 AM
 jdavis
Contributing User

Join Date: Jan 2003
Location: Texas
Posts: 171
Time spent in forums: 2 Days 20 h 3 m 24 sec
Reputation Power: 27
Thanks, Dan.

#4
December 9th, 2009, 04:30 PM
 jdavis
Contributing User

Join Date: Jan 2003
Location: Texas
Posts: 171
Time spent in forums: 2 Days 20 h 3 m 24 sec
Reputation Power: 27
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 05:40 PM.

#5
December 9th, 2009, 05:45 PM
 ManiacDan
Sarcky

Join Date: Oct 2006
Location: Pennsylvania, USA
Posts: 10,499
Time spent in forums: 2 Months 3 Weeks 5 Days 8 h 34 m 4 sec
Reputation Power: 6300
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

#6
December 9th, 2009, 05:52 PM
 jdavis
Contributing User

Join Date: Jan 2003
Location: Texas
Posts: 171
Time spent in forums: 2 Days 20 h 3 m 24 sec
Reputation Power: 27
Thanks Dan, I appreciate it.

#7
December 10th, 2009, 08:47 AM
 ishnid
kill 9, \$\$;

Join Date: Sep 2001
Location: Shanghai, An tSín
Posts: 6,896
Time spent in forums: 4 Months 2 Weeks 1 Day 23 h 59 m 14 sec
Reputation Power: 3886
Quote:
 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?

#8
December 10th, 2009, 09:42 AM
 jdavis
Contributing User

Join Date: Jan 2003
Location: Texas
Posts: 171
Time spent in forums: 2 Days 20 h 3 m 24 sec
Reputation Power: 27
Quote:
 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 10:03 AM.

#9
December 10th, 2009, 10:07 AM
 ManiacDan
Sarcky

Join Date: Oct 2006
Location: Pennsylvania, USA
Posts: 10,499
Time spent in forums: 2 Months 3 Weeks 5 Days 8 h 34 m 4 sec
Reputation Power: 6300
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

#10
December 10th, 2009, 10:29 AM
 jdavis
Contributing User

Join Date: Jan 2003
Location: Texas
Posts: 171
Time spent in forums: 2 Days 20 h 3 m 24 sec
Reputation Power: 27
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.

#11
December 11th, 2009, 02:16 PM
 ManiacDan
Sarcky

Join Date: Oct 2006
Location: Pennsylvania, USA
Posts: 10,499
Time spent in forums: 2 Months 3 Weeks 5 Days 8 h 34 m 4 sec
Reputation Power: 6300
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

 Viewing: Dev Shed Forums > Programming Languages - More > Regex Programming > Limiting number of digits