(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. | [reply] [d/l] [select] |
|
| [reply] |
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 | [reply] [d/l] [select] |
|
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
| [reply] |
|
| [reply] |
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
| [reply] [d/l] |
|
| [reply] |
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 | [reply] [d/l] [select] |
|
| [reply] |
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.
| [reply] |
|
...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
| [reply] |
|
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?
| [reply] |
|
| [reply] |
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 | [reply] [d/l] |
A reply falls below the community's threshold of quality. You may see it by logging in. |