in reply to [SOLVED] How do I determine with a regular expression whether a scalar is a number/whole/integer/float?

I am curious as to why you even want/need to do this?

It might be that you are asking either a home work question or the wrong question for a practical application. I am having trouble understanding your application that requires this distinction between C data types.

If you want to know if some string is valid in a numeric context, let Perl figure it out by simply adding "zero" to that number. If that is not a valid number, eg. "1.1.1", you will get a warning error message.

How to intercept this warning message and do something about it is different than what you have asked. Anyway some very simple code is attached that will generate a warning message if a "number" is not a "number"...

#!/usr/bin/perl use strict; use warnings; $| =1; #turn off STDIO buffering #this causes the error messages to STDERR #to appear closer to the standard print stuff my @numbers = qw(1 -1 123.1 0.1 1E6 ); foreach my $number (@numbers) { print "$number: \t", $number+0,"\n"; } print "now weirder stuff...\n\n"; @numbers = qw (1.1.1 4-1-1 --2); foreach my $number (@numbers) { print "$number: \t", $number+0,"\n"; } __END__ OUTPUT: 1: 1 -1: -1 123.1: 123.1 0.1: 0.1 1E6: 1000000 now weirder stuff... Argument "1.1.1" isn't numeric in addition (+) at C:\PerlTemp\testnume +ric2.pl line 19. 1.1.1: 1.1 Argument "4-1-1" isn't numeric in addition (+) at C:\PerlTemp\testnume +ric2.pl line 19. 4-1-1: 4 Argument "--2" isn't numeric in addition (+) at C:\PerlTemp\testnumeri +c2.pl line 19. --2: 0
  • Comment on Re: How do I determine with a regular expression whether a scalar is a number/whole/integer/float?
  • Download Code

Replies are listed 'Best First'.
Re^2: How do I determine with a regular expression whether a scalar is a number/whole/integer/float?
by thanos1983 (Parson) on Jul 12, 2015 at 10:35 UTC

    Hello Marshall,

    I want to be able to capture and understand different numbers coming in, not strings. I know that there are many examples how to check if the string is a number or an integer for example (A function to determine if a string is numeric).

    I know that there are modules for this purpose (Scalar::Util).

    But my goal is that I want with the use of a regular expression to determine what "category" is e.g. (integer, decimal, float).

    This is the reason that I define my array my @numbers = (1, -1, 123.1, 0.1); without the qw so the values will not be strings but numbers.

    Thank for you for your time and effort reading and replying to my question.

    Seeking for Perl wisdom...on the process of learning...not there...yet!

      But my goal is that I want with the use of a regular expression to determine what "category" is e.g. (integer, decimal, float).

      This is the reason that I define my array my @numbers = (1, -1, 123.1, 0.1); without the qw so the values will not be strings but numbers.

      What does a regular expression match against? Yup, a string.

      So, no matter how you initialize your array, for the purpose of comparison against a pattern, its elements are converted into strings.

      All conversions from string to number, from number to string, from integer to float and so on are done under the hood by perl, if necessary.

      Read perldata. - A scalar value (SV) has various slots: IV (integer), PV (string pointer), NV (numeric value). The currently active slot is determined by the FLAGS field of the scalar:

      use Devel::Peek; $c = 1; Dump $c; $c = "2"; Dump $c; $c = 3.141592653; Dump $c; __END__ SV = PVNV(0x176e4d0) at 0x1776f20 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 1 NV = 1.23456789 PV = 0 SV = PVNV(0x176e4d0) at 0x1776f20 REFCNT = 1 FLAGS = (POK,pPOK) IV = 1 NV = 1.23456789 PV = 0x17a7900 "2"\0 CUR = 1 LEN = 16 SV = PVNV(0x176e4d0) at 0x1776f20 REFCNT = 1 FLAGS = (NOK,pNOK) IV = 1 NV = 3.141592653 PV = 0x17a7900 "2"\0 CUR = 1 LEN = 16

      Note that after assigning $c the (shortened ;-) value of PI, the other slots - IV, PV - retain their previous values, but the FLAGS field now refers to NV: (NOK,pNOK).

      Incrementing the string " 2 ", which to perl looks like a number, results in the allocation of a integer slot which holds the value 3 - and adding 0.141592653 results in the allocation of a NV slot:

      use Devel::Peek; $c = " 2 "; Dump $c; $c++; Dump $c; $c+= 0.141592653; Dump $c; __END__ SV = PV(0x13f85f0) at 0x17c2de8 REFCNT = 1 FLAGS = (POK,pPOK) PV = 0x17e5820 " 2 "\0 CUR = 3 LEN = 16 SV = PVIV(0x1171478) at 0x17c2de8 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 3 PV = 0x17e5820 " 2 "\0 CUR = 3 LEN = 16 SV = PVNV(0x17ba4d0) at 0x17c2de8 REFCNT = 1 FLAGS = (NOK,pNOK) IV = 3 NV = 3.141592653 PV = 0x17e5820 " 2 "\0 CUR = 3 LEN = 16
      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'