tags:

views:

523

answers:

6

Examples:

"1"     yes
"-1"    yes
"- 3"   no
"1.2"   yes
"1.2.3" no
"7e4"   no  (though in some cases you may want to allow scientific notation)
".123"  yes
"123."  yes
"."     no
"-.5"   yes
"007"   yes
"00"    yes
+4  A: 

This allows for optional "+" and "-" in front. And allows trailing or initial whitespace.

/^\s*[+-]?(?:\d+\.?\d*|\d*\.\d+)\s*$/
dreeves
using \b instead of \s* may be slightly more efficient
SquareCog
This accepts 000
Motti
A: 

Depending on the language you are coding in this functionality may already exist.

EBGreen
A: 

A Perl-compatible regex, allowing for optional sign (+/-), option trailing and initial whitespace, and not allowing things like '17.' or '-14.' which aren't valid decimal fractions. It does however allow things like '.5' or '-.7', which feel like valid decimal representations; if you don't want that, change the \d* to \d+.

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

Note that this tests for decimal fractions, not reals; strictly speaking there are reals which cannot be represented as decimal fractions (at least, in a finite space).

James Aylett
I do want to count "17." as valid though.
dreeves
+2  A: 

Matches all specified examples, doesn't capture any groups:

^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$


To not match "1." (etc):

^[+-]?(?:\d+(?:\.\d+)?|\.\d+)$


Doesn't bother with whitespace (use a trim function).

Peter Boughton
+4  A: 

There are several alternatives. First, using a zero-width look-ahead assertion allows you to make the rest of the regex simpler:

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

If you want to avoid the look-ahead, then I'd try to discourage the regex from back-tracking:

/^[-+]?(?:\.\d+|\d+(?:\.\d*)?)$/
/^[-+]?(\.\d+|\d+(\.\d*)?)$/ # if you don't mind capturing parens

Note that you said "base 10" so you might actually want to disallow extra leading zeros since "014" might be meant to be octal:

/^[-+]?(?:\.\d+|(?:0|[1-9]\d*)(?:\.\d*)?)$/
/^[-+]?(\.\d+|(0|[1-9]\d*)(\.\d*)?)$/

Finally, you might want to replace \d with [0-9] since some regexes don't support \d or because some regexes allow \d to match Unicode "digits" other than 0..9 such as "ARABIC-INDIC DIGIT"s.

/^[-+]?(?:\.[0-9]+|(?:0|[1-9][0-9]*)(?:\.[0-9]*)?)$/
/^[-+]?(\.[0-9]+|(0|[1-9][0-9]*)(\.[0-9]*)?)$/
tye
Tye, how would one do this from BASH? Tnx.
Richard T
+2  A: 

The regular expression in perlfaq4: How do I determine whether a scalar is a number/whole/integer/float? does what you want, and it handles the "e" notation too.

while( <DATA> )
    {
    chomp;

    print /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/ ?
     "$_ Works\n"
     :
     "$_ Fails\n"
     ;
    }

__DATA__
1
-1
- 3
1.2
1.2.3
7e4
.123
123.
.
-.5
brian d foy