Beefy Boxes and Bandwidth Generously Provided by pair Networks DiBona
Syntactic Confectionery Delight
 
PerlMonks  

Matching an integer between 0 and 100

by McDarren (Abbot)
on Sep 01, 2009 at 15:43 UTC ( #792689=perlquestion: print w/ replies, xml ) Need Help??
McDarren has asked for the wisdom of the Perl Monks concerning the following question:

Howdy :)

This is just something that came up in a casual email exchange today. And I've no particular reason for posing the question here other than curiosity, and perhaps providing the opportunity for those with plenty of regex fu to show their stuff :)

"How would you construct a regex to match an integer between 0 and 100?"

My regex fu is only average at best, but after a couple of minutes I came up with:

perl -le 'for (qw/0 1 19 32.4 100 77 138 342.1/) { print "$_ is ", /^( +?:100|\d\d?)$/ ? "valid input" : "invalid input"}'
Which gives:
0 is valid input 1 is valid input 19 is valid input 32.4 is invalid input 100 is valid input 77 is valid input 138 is invalid input 342.1 is invalid input

Solves the "problem", but hard-coding the 100 in the pattern is pretty horrible, I think.

So how would others do this?

Cheers,
Darren

Comment on Matching an integer between 0 and 100
Select or Download Code
Re: Matching an integer between 0 and 100
by JavaFan (Canon) on Sep 01, 2009 at 15:49 UTC
    First of all, I would never ever combine \d and hardcoded numbers. Your regexp will match 0 to 99 in more than a dozen scripts, but 100 only in western numerals.

    Given that, I'd write it as /^(?:[0-9]{1,2}|100)$/. Or, if I wanted to be lazy: do {local $" = "|"; /^(?:@{[0..100]})$/};.

Re: Matching an integer between 0 and 100
by ikegami (Pope) on Sep 01, 2009 at 16:42 UTC

    Your pattern matches 0 and 100 even though neither are between 0 and 100. Is your question wrong or is your solution wrong?

    Solutions for "integers between 0 and 100":

    my $pat = qr/ ([0-9]+) (?(?{ my $n = $^N; $n <= 0 || $n >= 100 })(?!)) /x;
    my $pat = qr/0|[1-9][0-9]?/;
    my ($pat) = map qr/$_/, join '|', #map quotemeta, 1..99;
    use Regexp::List qw( ); my $pat = Regexp::List->new()->list2re( 1..99 );

    Solutions for "integers from 0 to 100":

    my $pat = qr/ ([0-9]+) (?(?{ my $n = $^N; $n < 0 || $n > 100 })(?!)) /x;
    my $pat = qr/0|100|[1-9][0-9]?/;
    my ($pat) = map qr/$_/, join '|', #map quotemeta, 0..100;
    use Regexp::List qw( ); my $pat = Regexp::List->new()->list2re( 0..100 );

    In all cases, you'll need to anchor the pattern as appropriate.

    The first solution of each set accepts leading zeroes. Easily changed.
    The bottom three solutions of each set don't accept leading zeroes. Easily changed.

    Update: Oops. Accidentally omitted a "?" from my patterns.

      "Is your question wrong or is your solution wrong?"
      heh... yes. The question is wrong. It should be "from" "to".
      I'll blame the guy that originally wrote it ;)
Re: Matching an integer between 0 and 100
by Anonymous Monk on Sep 01, 2009 at 17:50 UTC

    I know this doesn't really answer your question, but in any real world situation, for this type of problem I'd generally solve the two criteria separately for maximum re-usability and adaptability.

    Data::Validate has more robust implementations of both of these functions

    if ( is_integer($value) && is_between_inclusive($value,0,100) ){ ... } sub is_integer{ my $value = shift; return $value =~/^[-]?\d+$/; } sub is_between_inclusive{ my ($value,$min,$max) = @_; return(($value >= $min) && ($value <= $max)); }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://792689]
Approved by MidLifeXis
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2014-04-20 04:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (485 votes), past polls