Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

isAlpha / isNumeric

by Jamnet (Scribe)
on Mar 22, 2001 at 17:22 UTC ( #66320=perlquestion: print w/replies, xml ) Need Help??

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

Hi There

I am writing the small subroutine which will validate if the contents of the variable is alphabet or numeric. Below mentioned is my solution but I think there must be better way to do the same. So I would request all the Monks out there to help me with the same.

#!/usr/bin/perl -w my $a = "aBcdeFG"; if ($a =~ /[a-z]+/i) { print "Alphabet\n"; } else { print "Numeric\n"; }
Regards

Joel

Replies are listed 'Best First'.
(Ovid) Re: isAlpha / isNumeric
by Ovid (Cardinal) on Mar 22, 2001 at 17:42 UTC
    Small logic error, there:
    #!/usr/bin/perl -w my $a = "aBcdeFG"; if ($a =~ /^[a-z]+$/i) { print "Alphabet\n"; } elsif ($a =~ /^\d+$/ ) { print "Numeric\n"; } else { print "Neither\n"; }
    First, I added the beginning and end of line anchors (^$). Your script would have determined that "123a123" was "alphabetic". That may be what you want, but I suspect not. Further, if it wasn't alphabetic, everything else would have resulted in "numeric", including something like "#$*&%(*&@", which is again probably something you don't want.

    Incidentally, such regular expressions are how alphabetic and numeric data is identified. With regular expressions, there is really no need for special functions to test for these. If you must have them, you can write something like the following:

    sub IsNumeric { my $val = shift; if ( defined $val ) { return $val =~ /^\d+$/ ? 1 : 0; } else { warn "IsNumeric requires an argument!"; } }
    Cheers,
    Ovid

    Update: Sheesh. Trimbach totally beat me to the punch there and said exactly the same thing. Sigh.

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      Hi Ovid,

      Thanks a lot for your support.

      Regards

      Joel

Re: isAlpha / isNumeric
by Trimbach (Curate) on Mar 22, 2001 at 17:36 UTC
    The way you're using regex's won't get you what you want. /[a-z]+/i will match a string with one or more upper and lower case letters (in a weird way, but it works) but there's lots of other characters in the world than just A-Z and "numbers." If $a="%_!@" your code will proudly proclaim that $a is "numeric" which it isn't, at least for my definition of numeric. :-D

    If what you want to do is distinguish between letters and numbers, you might try:

    #!/usr/bin/perl -w my $a = "aBcdeFG"; if ($a =~ /[A-Za-z]/) { # No i modifier needed print "Alphabet\n"; } elsif ($a =~ /\d/) { # \d matches 0-9 only print "Numeric\n"; } else { print "Non-numeric, non-alphabet\n"; }

    Gary Blackburn
    Trained Killer

      Hi Gary Blackburn,

      Thanks a lot, as I am new to Perl(<3 months), your response will surely help me get better. But I would personally request you to take a look at my 'Simple Pop3 Client' under 'Code Section' and give me your feedback

      Regards

      Joel

      Hi Gary Blackburn,

      Thanks a lot for your support.

      Regards

      Joel

Re: isAlpha / isNumeric
by davorg (Chancellor) on Mar 22, 2001 at 17:56 UTC

    More recent Perls (5.6?) support the POSIX [:class:] syntax, you you can do things like this:

    if (/^[:alpha:]+/) { print "string is alpha"; } elsif (/^[:digit:]+/) { print "string is digits" } else { print "sting is weird stuff"; }
    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

      Hi davorg,

      Thanks a lot for your support.

      Regards

      Joel

Re: isAlpha / isNumeric
by modred (Pilgrim) on Mar 22, 2001 at 17:48 UTC
    There are a couple of problems with the code you have.

    First, any white space or punctuation will be considered to be numeric - I somehow don't think that is what you want. This can be fixed by adding an elsif clause with a condition of $string =~ /^\d+$/. Of course, then you have to decide if white space and punctuation are valid inputs are not.

    Second, consider the strings "a2" and "2a" - both will be considered Alphabet but your code. There is at least one character in each string thus the match succeeds. You want to anchor the match, something like $string =~ /^[a-zA-Z]+$/.

    Third, are you sure that you want to use $a as a variable name. It has the same name as the built in sort variable and you did make it a my variable but to save yourself possible future bugs I would recommend against using $a (and $b) as temporary variables names.

    The tests would probably look something like

    if($string =~ /^[a-zA-Z]$/) # can also be written as /^[a-z]$/i { print "Alphabet\n"; } elsif($string =~ /^\d+$/) { print "Number\n"; } else { print "Other\n"; }
    Depending on the source of the data you may also need to use chomp on the variable to get rid of any trailing newlines.

    Edit: chipmunk 2001-03-22

      Hi modred,

      Thanks a lot for your support.

      Regards

      Joel

Re: isAlpha / isNumeric
by lhoward (Vicar) on Mar 22, 2001 at 18:03 UTC
    All the solutions that have been posted so far have serious internationalization/localization problem. They all make the assumption that A-Za-z are the only alphabetic characters. This is a very short-sighetd assumption. You're better off using the POSIX isalpha or isdigit functions which are locale aware.
      ...well, yeah. But if you ask me an "alphabet" regex (in any alphabet) has pretty limited utility. I've always used /\w/ which at least in Perl 5.6 is Internationalized (I think.)

      And without sparking any huge debate on the merits of internationalization everyone should program to the type of data they expect to have to deal with. If the poster's code is going to be used in an environment of all-English speakers there's no internationalization problem at all. If it's in a CGI on the Internet he/she may want to consider other options. Limiting code to one language is not prima facia a bad thing... internationalization is just one more area to optimize if you need it.

      Gary Blackburn
      Trained Killer

        I think that it is very shortsighted to assume that your "alphabet" is only A-Z when you can support characters from other alphabets with in your code with no additional effort. Even if your applicaiton is %100 targeted to a English speaking, US audience you will run into occasions where you want to use accented characters: El Niño, Björk, Café, etc.... IMHO, limiting your code to work on A-Z only is asking for trouble later on (like using a 2 digit year). Why limit yourself when you don't have to?
      Hi lhoward,

      Thanks a lot for your support.

      Regards

      Joel

Re: isAlpha / isNumeric
by McD (Chaplain) on Mar 22, 2001 at 21:54 UTC
    Just to add fuel to the fire, I'll point out that the concept of "is numeric" is open to a wide variety of interpretation. See the following snippet direct from the Cookbook Recipe 2.1:

    warn "has nondigits" if /\D/; warn "not a natural number" unless /^\d+$/; # rejects -3 warn "not an integer" unless /^-?\d+$/; # rejects +3 warn "not an integer" unless /^[+-]?\d+$/; warn "not a decimal number" unless /^-?\d+\.?\d*$/; # rejects .2 warn "not a decimal number" unless /^-?(?:\d+(?:\.\d*)?|\.\d+)$/; warn "not a C float" unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
    Peace,
    -McD
    A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (6)
As of 2023-09-26 09:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?