Re: Check for Positive Integer entry only
by kyle (Abbot) on May 09, 2007 at 17:33 UTC
|
You might want to look at Regexp::Common::number in general, but I don't see anything ready-made to do what you want. Here's a pattern I might use:
$dataEntry =~ m{ \A # beginning of string
\+? # optional plus sign
\d+ # one or more digits
\z # end of string
}xms
Using Regexp::Common, that might be:
use Regexp::Common qw( number );
$dataEntry =~ /$RE{num}{int}/ && $dataEntry == abs $dataEntry
If you want to allow for white space in your data entry, you could add \s* into your patterns.
Update: After consideration of the contributions of the other monks, I think this is a better expression than the one I have above:
m{ \A # beginning of string
\+? # optional plus sign
[0-9]* # optional digits, including zero
[1-9] # mandatory non-zero digit
[0-9]* # optional digits, including zero
\z # end of string
}xms
This incorporates Nkuvu's observation that a value of zero should not be allowed and mreece's suggestion that \d is not always the best way to match digits (though I find this counterintuitive). It also passes my own test suite. | [reply] [d/l] [select] |
Re: Check for Positive Integer entry only
by friedo (Prior) on May 09, 2007 at 17:16 UTC
|
if ( $DataEntry =~ /^\d+$/ ) {
print "good entry";
} else {
print "bad entry";
}
| [reply] [d/l] |
|
| [reply] |
|
That also passes for "123\n" which could be good or bad. Use \z instead of $ if you don't want to allow a trailing \n.
| [reply] [d/l] [select] |
Re: Check for Positive Integer entry only
by jasonk (Parson) on May 09, 2007 at 17:15 UTC
|
While !/d.*+ vaguely resembles a regular expression, I suspect you want to read perlre, because what you have there is not a regular expression (or perl for that matter, since it won't even compile.)
We're not surrounded, we're in a target-rich environment! |
---|
| [reply] [d/l] |
Re: Check for Positive Integer entry only
by swampyankee (Parson) on May 09, 2007 at 18:08 UTC
|
I think that this exact case is handled in the Camel Book.
The logic is quite straightforward:
#!perl
use strict;
use warnings;
while (<DATA>) {
chomp; # get rid of pesky newlines
if(is_integer_string($_)){
print "$_ is a valid integer string\n";
}
else {
print "$_ isn't a valid integer string\n";
}
}
sub is_integer_string {
# a valid integer is any amount of white space, followed
# by an optional sign, followed by at least one digit,
# followed by any amount of white space
return $_[0] =~ /^\s*[\+\-]?\d+\s*$/;
}
__DATA__
1
1234
+1234
-1234
A
1234+
+ 1234
Note that this does not check to see if the integer can be represented on your system. It also does not permit white space between the sign and the leading digit of the number being examined.
Oops! This will pass 0, which is not a positive integer, although it is a valid integer.
To correct the test replace this:
return $_[0] =~ /^\s*[\+\-]?\d+\s*$/;
with this
if(( $_[0] =~ /^\s*[\+\-]?\d+\s*$/) and ($_[0] > 0)) {
return 1;
}
else{
return undef;
}
Doubtless, this is not the most efficient method.
emc
Insisting on perfect safety is for people who don't have the balls to live in the real world.
—Mary Shafer, NASA Dryden Flight Research Center
| [reply] [d/l] [select] |
Re: Check for Positive Integer entry only
by Nkuvu (Priest) on May 09, 2007 at 17:44 UTC
|
Is there a place to donate or help fund this great site??
See the Offering Plate for contribution details.
| [reply] |
Re: Check for Positive Integer entry only
by mreece (Friar) on May 09, 2007 at 21:59 UTC
|
i'm not a big fan of \d, since it can lead to unexpected results: matching things that are "digits" but not useable as perl or database integers. when unicode enters the picture, there are 268 or so unicode characters that \d matches against.
what you probably want here is a string that starts with a number 1-9, followed by more numbers 0-9 (assuming that 03 is a bad entry), or just one or more numbers 0-9 (if 03 is a good entry).
if ($DataEntry =~ /^[1-9][0-9]*$/) {
print "good entry\n";
} else {
print "bad entry\n";
}
or
if ($DataEntry =~ /^[0-9]+$/) {
print "good entry\n";
} else {
print "bad entry\n";
}
| [reply] [d/l] [select] |
Re: Check for Positive Integer entry only
by chrism01 (Friar) on May 09, 2007 at 22:59 UTC
|
# +ve int, not inc zero, optional space, optional sign
$var1 =~ s/^\s+//; # leading whitespace
$var1 =~ s/\s+$//; # trailing whitespace
if( $var1 =~ /^[+]?\d+$/ && $var1 != 0 )
{
print "+ve int\n";
}
Cheers
Chris | [reply] [d/l] |
Re: Check for Positive Integer entry only
by shobhit (Sexton) on May 09, 2007 at 19:29 UTC
|
Do we absolutely need a RE to check for positive integer?
Can't we simply check for >0 ? | [reply] |
|
print 'no' if '1a' > 0;
print 'no' if .1 > 0;
| [reply] [d/l] |
|
Get the point now.
But this also means, that we may never be sure of the result of comparison operator.
Is there anyway, such
int 'comparison operator' int # returns the actual result
int 'comparison operator' string # returns an error
We could check for the type of both before comparing them, of course. But, thats not the point....
Something more simple than that, just compare and get the result or an error as the case may be.
| [reply] |
|
|
|
use strict;
use warnings;
my @tests = qw/12 1a 4 -3 0 0.1 .1/;
for (@tests) {
print "$_ => ";
no warnings qw/numeric/;
if ($_ eq int($_) && $_ > 0) {
print 'ok';
} else {
print 'bad';
}
print "\n";
}
__END__
C:\Perl\test>perl int_test.pl
12 => ok
1a => bad
4 => ok
-3 => bad
0 => bad
0.1 => bad
.1 => bad
| [reply] [d/l] [select] |
|
use strict;
use warnings;
use Test::More;
my @good = qw( 12 1 +1 1234 );
my @bad = qw( 1a -3 0.1 .1 0 +0 -0 );
plan 'tests' => scalar @good + scalar @bad;
ok( is_int( $_ ), "[$_] is int" ) for @good;
ok( ! is_int( $_ ), "[$_] is not int" ) for @bad;
sub is_int {
return ( $_[0] eq int( $_[0] ) && $_[0] > 0 );
}
__END__
1..11
ok 1 - [12] is int
ok 2 - [1] is int
not ok 3 - [+1] is int
# Failed test '[+1] is int'
# in perlmonks.pl at line 14.
ok 4 - [1234] is int
Argument "1a" isn't numeric in int at perlmonks.pl line 18.
ok 5 - [1a] is not int
ok 6 - [-3] is not int
ok 7 - [0.1] is not int
ok 8 - [.1] is not int
ok 9 - [0] is not int
ok 10 - [+0] is not int
ok 11 - [-0] is not int
# Looks like you failed 1 test of 11.
Oops. I should have named that is_positive_int, etc. | [reply] [d/l] [select] |