Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

How to identify a number datatype in a string?

( #2114=categorized question: print w/ replies, xml ) Need Help??
Contributed by BBQ on Jan 15, 2000 at 03:35 UTC
Q&A  > numbers


Description:

We all know that perl is good for it's so called lack of datatype declarations (and a bunch of other things). But what if you WANT to know if your string is an integer? Furthermore, what if your integer has already been formatted? This is the code that I came up with, but I feel it could be greatly improoved. Suggestions are > welcome!

Answer: How to identify a number datatype in a string?
contributed by chromatic

The Perl Cookbook suggests that the following regex will match C floats: $var =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d)?([Ee]([+-]?\d+))?$/; That may be overkill for your purposes, though.

Update: (Tue Jan 8 16:03:52 UTC 2002) Removed spurious left paren (thanks, Petruchio).

Answer: How to identify a number datatype in a string?
contributed by vroom

#!/usr/bin/perl # check for numbers with punctuation use Strict; # examples for "common-written" numbers foreach my $var ( # should be false '','foo 30','.20','20.',',20','20,', # should be numbers 0,100,'100.23','1,100.23' ) { if (IsANumber($var)) { print "True: $var\n"; } else { print "False: $var\n"; } } sub IsANumber { my $var = $_[0]; if ( # contains digits,commas and 1 period ($var =~ /(^[0-9]{1,}?$)|(\,*?)|(\.{1})/) && # does not contain alpha's, more than 1 period # commas or periods at the beggining and ends of # each line !($var =~ /([a-zA-Z])|(^[\.\,]|[\.\,]$)/) && # is not null ($var ne '') ) { return(1) } else { return(0) } }
Answer: How to identify a number datatype in a string?
contributed by astaines

USe an eval, it's correct (by definition) and avoids possible errors

my @numbers = ( '1', '2', '10', '1.2', '1e2', '1.02e2', '1.02e-2', 'e-2', 'er', 'et', '0er' ); foreach my $number (@numbers) { my $test = $number; eval { $test +=0; }; if ( $@ ) { print "$number isn't a number \n"; } }

{QA Editors note: This solution doesn't work as described. See Re: Answer: How to identify a number datatype in a string? for more explanation.}

Edited by davido: Repaired <code> tags, reformatted code. Added editorial note to clarify why this example is broken.

--

Anthony Staines

Answer: How to identify a number datatype in a string?
contributed by rbi

I think that both the Cookbook and vroom miss some valid numbers.
Here's my proposed checker. HOpe I don't get wrong ones, instead :)
Roberto

#!/usr/bin/perl # check for numbers with punctuation use strict; # examples for "common-written" numbers foreach my $var ( '','foo 30','.20','20.',',20','20,','1.3E2', '2..3','++3','2.3.', ,'..3', 0,100,'100.23','1,100.23','-3E-2' ) { print "String: $var\n"; if (IsANumber($var)) { print "vroom says True, "; } else { print "vroom says False, "; } if (IsANumberCookbook($var)) { print "Cookbook says True, "; } else { print "Cookbook says False, "; } if (IsANumberMine($var)) { my $out = $var * $var; print "I say True and square is $out\n\n"; } else { print "I say False\n\n"; } } sub IsANumber { # vroom version my $var = $_[0]; if ( # contains digits,commas and 1 period ($var =~ /(^[0-9]{1,}?$)|(\,*?)|(\.{1})/) && # does not contain alpha's, more than 1 period # commas or periods at the beggining and ends of # each line !($var =~ /([a-zA-Z])|(^[\.\,]|[\.\,]$)/) && # is not null ($var ne '') ) { return(1) } else { return(0) } } sub IsANumberCookbook { # Perl Cookbook version my $var = $_[0]; if ( $var =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d)?([Ee]([+-]?\d+) +)?$/ ) { return(1) } else { return(0) } } sub IsANumberMine { # my version my $var = $_[0]; if ( $var =~ /^([+-]?)(\d+\.|\.\d+|\d+)\d*([Ee]([+-]?\d+)) +?$/ ) { return(1) } else { return(0) } }
Answer: How to identify a number datatype in a string?
contributed by jdhedden

Scalar::Util has a function looks_like_number() for just this purpose. It is included in Perl 5.8, or you can get it from CPAN.

You can use looks_like_number() in conjunction with int() to tell what type of number you have.

#!/usr/bin/perl use strict; use warnings; use Scalar::Util qw(looks_like_number); my $x = $ARGV[0]; if (looks_like_number($x)) { if (int($x) == $x) { print("$x is an integer\n"); } else { print("$x is numeric\n"); } } else { print("Your input was not numeric\n"); }
Answer: How to identify a number datatype in a string?
contributed by Anonymous Monk

Identify String or number: Ben Young;
I tried this and it only fails on $x = '0.0', but not $x = 0.0

if (($m == 0) && !($m eq '0')) {print "string\n";} else {print "number +\n";}

It works since PERL treats strings as 0 in numeric tests. (It also pulls numbers out of strings if the numbers come first)

Edited by davido: Added code tags. Reformatted.

Answer: How to identify a number datatype in a string?
contributed by Anonymous Monk

The first regex given on this page to identify a number fails with:

"1.233e+23", "1.233"

but succeeds with:
"1.2e+233"

Appears to be some sort of problem with multiple digits after a decimal point.

The regex is:

/^([+-]?)(?=\d|\.\d)\d*(\.\d)?([Ee]([+-]?\d+))?$/

A slightly modified version which does work for the given cases:

/^([+-]?)(?=\d|\.\d+)\d*(\.\d+)?([Ee]([+-]?\d+))?$/

The only difference is the extra plus's after each \.

Edited by davido: Added <code> tags.

Answer: How to identify a number datatype in a string?
contributed by Bilbo

The mehod suggested by astaines works but the script he gives does not because perl only warns about adding to non-numeric variables, so this is not caught by the eval. It is therefore necessary to make warnings fatal within the eval block:

sub is_number { my $test = shift; eval { local $SIG{__WARN__} = sub {die $_[0]}; $test += 0; }; if ($@) {return 0;} else {return 1;} }

Please (register and) log in if you wish to add an answer



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others having an uproarious good time at the Monastery: (6)
    As of 2014-12-28 13:21 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      Is guessing a good strategy for surviving in the IT business?





      Results (181 votes), past polls