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

Problem with pattern matching

Need in -if- statement that will detect when a 2 char string contains a non digit.( I’ve already checked the string's lenght so it's guaranteed to be 2 chars long.) In other words. The string can contain "00","01"."02"…"99" but NOT stuff like " 0". "0 ", "9A", "Z7"...

if ($my_dat =~ /^[0-9]/ ) {some code here;}

Works if the 1st char is not a digit ( catches stuff like " 0" and "A4" ) but misses stuff if 2nd char is not a digit ( Misses stuff like "0 " and "7W")

Can someone help ?

Code tags added by davido per consideration. See Writeup Formatting Tips for explanation.

Replies are listed 'Best First'.
Re: Question on pattern matching
by Limbic~Region (Chancellor) on Jun 16, 2005 at 19:41 UTC
    Joe_Cullity,
    If you already know that the string is two characters you can just say
    if $str =~ /\D/ { print "non-digit" }
    If you want to kill two birds with one stone, you can verify length and digitness in one statement:
    if $str !~ /^\d\d$/ { print "wrong length or contains non-digits" }

    Cheers - L~R

Re: Question on pattern matching
by Zaxo (Archbishop) on Jun 16, 2005 at 19:43 UTC

    To test if the string is exactly two digits, anchor beginning and end and use a quantifier,

    if ($my_dat !~ /^\d{2}$/) { # some code here }
    The !~ op negates the match so that the bracketed code is executed if $my_dat is different from two digits.

    After Compline,
    Zaxo

Re: Question on pattern matching
by ikegami (Patriarch) on Jun 16, 2005 at 19:40 UTC

    Check for a non-digit:

    if ($my_dat =~ /[^0-9]/) { # $my_dat contains a non-digit. ... }

    or check for all digits:

    if ($my_dat =~ /^[0-9]+$/) { # $my_dat only contains digits. ... }

    Update: If you need to make sure the string is only two characters long:

    if ($my_dat =~ /^[0-9]{2}$/) { # $my_dat only contains digits. # $my_dat is exactly two characters long. ... }

      This also works:

      if ($my_dat eq sprintf('%02d', do { no warnings; 0+$my_dat })) { # $my_dat only contains digits. # $my_dat is exactly two characters long. ... }
Re: Question on pattern matching
by Transient (Hermit) on Jun 16, 2005 at 19:42 UTC
    you want
    if ( $my_dat =~ /[^0-9]/ ) { # code here to handle the non-digits
    your regexp looks for the beginning of the line followed by a digit... the one above looks for anything anywhere that is a NON-digit.
      /[^0-9]/ is more concisely written /\D/.
Re: Question on pattern matching
by shady (Sexton) on Jun 16, 2005 at 22:00 UTC
    If you want get match only in digits, to solve your problem write so: if ($my_dat =~ /^0-9$/ ) {some code here;} or if ($my_dat =~ /^\d+$/ ) {some code here;}
Re: Question on pattern matching
by sh1tn (Priest) on Jun 16, 2005 at 22:06 UTC
    If the string is only two digits, you can use faster check with hash keys existence:
    my %digits = map{ '0'x(2-length($_)).$_, 1 }0..99; #now keys in %digits are from 00,01 ... to 99 if( exists $digits{$my_dat} ){ ... }