Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Detect presence of numbers 1-9

by kiat (Vicar)
on Apr 08, 2002 at 08:52 UTC ( #157388=perlquestion: print w/replies, xml ) Need Help??

kiat has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

Greetings :)

Suppose you want to accept a scalar value containing only numbers from 1-5, how do you do that? Other numbers such as '0' and '6' and other non-numeric characters should not be accepted (so, $scalar1 = '1334' is accepted, $scalar2 = '1340' is out and so is $scalar3 = '155q')

kiat

Replies are listed 'Best First'.
Re: Detect presence of numbers 1-9
by projekt21 (Friar) on Apr 08, 2002 at 08:57 UTC

    This looks like a task for a regex:

    if ( $scalar =~ /^[12345]+$/ ) { print "match"; } else { print "no match"; }

    Update: as crazyinsomniac pointed out you can also write:

    if ( $scalar !~ /[^12345]/ ) { print "match"; }

    alex pleiner <alex@zeitform.de>
    zeitform Internet Dienste

      if ( $scalar !~ /[^12345]/ ) { print "match"; }

      Hmm, that double negative sure is confusing. Maybe simplifying it would be a little clearer (I know regexes pretty well and I had to think about this for a second...)

      if ( $scalar =~ /[^12345]/ ) { print "Illegal parameter: $scalar"; } else { print "Acceptable parameter: $scalar"; }
      Maybe some would disagree but to me I like to say my regexes out loud to understand them and I find

      if it matches any character that isn't a 1-5 then it is bad

      much easier (read faster) to understand than

      if it does not match any character that is not a 1-5 then it is good.

      I agree im probably being a bit pedantic but I think you can see what I mean...

      Yves / DeMerphq
      ---
      Writing a good benchmark isnt as easy as it might look.

      if ( $scalar =~ /^[12345]+$/ ) {

      Please note that $ also matches before a trailing \n character, and that this regex also matches "111\n". But I'd go for the negative match anyway, because it seems more natural to me.

      U28geW91IGNhbiBhbGwgcm90MTMgY
      W5kIHBhY2soKS4gQnV0IGRvIHlvdS
      ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
      geW91IHNlZSBpdD8gIC0tIEp1ZXJk
      

      If you do have a sequence like that, you can make it look even cleaner by writing it:
      $scalar =~ /^[1-5]+$/
      or
      $scalar !~ /[^1-5]/

      You have moved into a dark place.
      It is pitch black. You are likely to be eaten by a grue.
        I'd avoid the double-negative tests because they would match the empty string (and undef, but you do have warnings enabled, right?). In most cases, it's usually better to state what you want, not what you don't want. :-)

        ------
        We are the carpenters and bricklayers of the Information Age.

        Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      # or even: $scalar =~ /[^1-5]/ ? &is_bad : &is_good; print $scalar =~ /[^1-5]/ ? "bad" : "OK!"; $scalar !~ /[^1-5]/ && print "OK!"; print "OK!" unless $scalar =~ /[^1-5]/; print "OK!" if $scalar !~ /[^1-5]/;

      STATMWTDI cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: Detect presence of numbers 1-9
by jmcnamara (Monsignor) on Apr 08, 2002 at 09:15 UTC

    You could use a regex to either match the characters that you want or alternatively to not match the characters that you don't want:
    #!/usr/bin/perl -wl use strict; my $scalar = '1335'; print "Found" if $scalar =~ /^[1-5]+$/; print "Found" if $scalar !~ /[^1-5]/;

    --
    John.

Re: Detect presence of numbers 1-9
by perlplexer (Hermit) on Apr 08, 2002 at 13:01 UTC
    unless ($str =~ tr/1-5//c){ print "Valid\n"; }else{ print "Invalid\n"; }

    --perlplexer
Re: Detect presence of numbers 1-9
by simon.proctor (Vicar) on Apr 08, 2002 at 09:46 UTC
    If you felt brave enough you could combine the above with tie and then make all the tests transparent to your program. Look at the tie manpage for details.

      If you felt brave enough you could combine the above with tie and then make all the tests transparent to your program.

      A try (untested)

      package Tie::Match; use strict; sub TIESCALAR { my ($class, $regex) = @_; return bless [undef, $regex], $class; } sub STORE { my ($self, $new) = @_; $self->[0] = $new =~ $self->[1] ? $new : undef; } sub FETCH { my ($self) = @_; return $_->[0]; } sub UNTIE { } sub DESTROY { } __END__ =head1 NAME Tie::Match - Tie a scalar that is undef when not matching a regex =head1 SYNOPSIS tie my $scalar, 'Tie::Match', qr/^[1-5]+$/; while ($scalar = <>) { if (defined $scalar) { print "Match: $scalar\n"; } else { print "No match.\n"; } } =head1 DESCRIPTION Ties a scalar. The scalar can be set, but will be undef if the new value does not match the given regex. =head1 URL http://perlmonks.org/?node_id=157404 =cut

      U28geW91IGNhbiBhbGwgcm90MTMgY
      W5kIHBhY2soKS4gQnV0IGRvIHlvdS
      ByZWNvZ25pc2UgQmFzZTY0IHdoZW4
      geW91IHNlZSBpdD8gIC0tIEp1ZXJk
      

      I think, this is a huge overkill :) Imagine, we'd have to compose a Tie::FooThing package every time we face a simple branching algorithm? What this guy needs is probably some good intro into regexen and some good example variants of code, like tachyon provided.
•Re: Detect presence of numbers 1-9
by merlyn (Sage) on Apr 08, 2002 at 16:20 UTC

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (9)
As of 2021-05-07 13:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Perl 7 will be out ...





    Results (91 votes). Check out past polls.

    Notices?