RegEx that matches positive numbers

Multi tool use


RegEx that matches positive numbers
I need to write a regex to allow only positive number ( integers or decimals). I have found this:
/^(?!(?:0|0.0|0.00)$)[+]?d+(.d|.d[0-9])?$/
but it just accepts up to 2 decimal places. What changes do I have to make, so that it can accept any number of decimal places?
Also where can I find a good tutorial for learning regex.
Thanks beforehand
04
04
¼
3⁴
0⁴
4⁰
Ⅷ
ⅽ̄
ↈ
π
⑮
⓯
The basic test cases need to minimally be +2, 2, -2, 2., .2, 2.2, -2.2, +2.2 — and then again with all those twos turned to zeroes. The answer you accepted fails on some of those. You should probably also add 6e23, 6e-23, and 0e23 to your test cases. And we haven't considered −1, which is an interesting case.
– tchrist
Dec 16 '10 at 23:48
possible duplicate of Learning Regular Expressions
– hopper
Feb 27 '15 at 19:17
This is really not the kind of thing you should be doing with regexes. As the various complicated answers (and their mistakes) illustrate. Think outside the box. Look for an alternative approach.
– Stephen C
yesterday
4 Answers
4
This would be my way: ^[+]?d+([.]d+)?$
EDIT: If you want to allow something like .23
, you could use ^[+]?([.]d+|d+([.]d+)?)$
EDIT: tchrist insists on this one: allowing 4.
, you could use ^[+]?([.]d+|d+[.]?d*)$
^[+]?d+([.]d+)?$
.23
^[+]?([.]d+|d+([.]d+)?)$
4.
^[+]?([.]d+|d+[.]?d*)$
Explanation:
Note: This will not accept a negative number, which is what you ultimately want.
I've added this (?!(?:0|0.0|0.00)$) , to prevent the user from entering 0/0.0/0.00 , but what if it enters 0.000. How can I say "0.any number of zeros" ?
– eddy
Dec 16 '10 at 22:55
@eddy -- So you don't want to accept a number that ultimately translates to pure 0?
– BeemerGuy
Dec 16 '10 at 22:58
Fails on
.23
, you know.– tchrist
Dec 16 '10 at 23:07
.23
@tchrist -- no it doesn't, the
d+
will force at least one digit before it gets to the decimal point.– BeemerGuy
Dec 16 '10 at 23:10
d+
@BeemerGuy: That’s precisely why it fails: because
".23"
is a perfectly valid positive number, but your pattern erroneously rejects it.– tchrist
Dec 16 '10 at 23:11
".23"
The short answer is that you need this pattern:
^(?!(?:^[-+]?[0.]+(?:[Ee]|$)))(?!(?:^-))(?:(?:[+-]?)(?=[0123456789.])(?:(?:(?:[0123456789]+)(?:(?:[.])(?:[0123456789]*))?|(?:(?:[.])(?:[0123456789]+))))(?:(?:[Ee])(?:(?:[+-]?)(?:[0123456789]+))|))$
The long answer is contained in the following program:
#!/usr/bin/perl
use strict;
use warnings qw<FATAL all>;
my $number_rx = qr{
# leading sign, positive or negative
(?: [+-] ? )
# mantissa
(?= [0123456789.] )
(?:
# "N" or "N." or "N.N"
(?:
(?: [0123456789] + )
(?:
(?: [.] )
(?: [0123456789] * )
) ?
|
# ".N", no leading digits
(?:
(?: [.] )
(?: [0123456789] + )
)
)
)
# abscissa
(?:
(?: [Ee] )
(?:
(?: [+-] ? )
(?: [0123456789] + )
)
|
)
}x;
my $negative_rx = qr{ ^ - }x;
my $zero_rx = qr{ ^ [-+]? [0.]+ (?: [Ee] | $ ) }x;
my $positive_rx = qr{
^
(?! $zero_rx )
(?! $negative_rx )
$number_rx
$
}x;
my @test_data = qw{
-2 2 +2 2. -1 1 +1 1.
0 +0 -0 .0 0.
1.3 -3.2 5.13.7
00.00 +00 -00 +0-1
0000.
McGillicuddy
+365.2425
6.02e23
.0000000000000000000000000000000000000000000000000000000000000000000
.00000000000000000000000000000000000000000000000000000000000000000000000001
.03 0.3 3.0
0e50 0e-50
1e50 1e+50 1e-50
};
for my $n (@test_data) {
printf "%s is%s a positive number.n",
$n, $n =~ /$positive_rx/ ? "" : " not";
}
The test results are:
-2 is not a positive number.
2 is a positive number.
+2 is a positive number.
2. is a positive number.
-1 is not a positive number.
1 is a positive number.
+1 is a positive number.
1. is a positive number.
0 is not a positive number.
+0 is not a positive number.
-0 is not a positive number.
.0 is not a positive number.
0. is not a positive number.
1.3 is a positive number.
-3.2 is not a positive number.
5.13.7 is not a positive number.
00.00 is not a positive number.
+00 is not a positive number.
-00 is not a positive number.
+0-1 is not a positive number.
0000. is not a positive number.
McGillicuddy is not a positive number.
+365.2425 is a positive number.
6.02e23 is a positive number.
.0000000000000000000000000000000000000000000000000000000000000000000 is not a positive number.
.00000000000000000000000000000000000000000000000000000000000000000000000001 is a positive number.
.03 is a positive number.
0.3 is a positive number.
3.0 is a positive number.
0e50 is not a positive number.
0e-50 is not a positive number.
1e50 is a positive number.
1e+50 is a positive number.
1e-50 is a positive number.
+1 Just curious why, in the abscissa expression, you use an
"OR nothing"
alternative instead of just making that whole thing optional with a ?
i.e. Why (?:foo|)
vs (?:foo)?
?– ridgerunner
Mar 24 '11 at 18:10
"OR nothing"
?
(?:foo|)
(?:foo)?
@ridgerunner: I no longer recall, but probably it was because that mapped to how I was thinking about it at the time. Certainly it makes no difference which way it’s written.
– tchrist
Mar 24 '11 at 20:20
This should do it.
+?(d+(.(d+)?)?|.d+)
There are tons of regular expression tutorials out there, here is one of them:
http://www.cs.tut.fi/~jkorpela/perl/regexp.html
Fails on
.14159
, you know.– tchrist
Dec 16 '10 at 23:08
.14159
Good catch tchrist, I put in a fix for that. It seems like it should be simpler, but the only way I could do it was to add a second case
– killdash9
Dec 16 '10 at 23:14
That fails on
100.
, you know. :(– tchrist
Dec 16 '10 at 23:34
100.
@tchrist it's getting more complicated :) but the new expression should handle that. Seems like it should be simpler at first blush.
– killdash9
Dec 16 '10 at 23:39
@Russ: these things are always harder than they seem. Look at my test cases.
– tchrist
Dec 16 '10 at 23:42
This one is kinda simple — /d*(.d*)?/g
/d*(.d*)?/g
Update: this one doesn't match empty strings — /(.)?d+(.d*)?/g
Tested on "-1.5 0 12. -123.4. 15 -2. .4"
/(.)?d+(.d*)?/g
You say simple, but your regex actually matches an empty string currently.
– FrankerZ
yesterday
@FrankerZ my bad, corrected the answer
– Alex Shevchenko
yesterday
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Is
04
a positive number? Note that that is not04
; the code points differ. Similarly, is¼
a positive number? What about3⁴
? I believe you’ll find that0⁴
is not a positive number, yet4⁰
actually is. How do you feel aboutⅧ
, orⅽ̄
in lieu ofↈ
? Isn’tπ
a positive number? Did you know that⑮
is a positive number, but that⓯
is a negative number? Have you considered ` 𝟑 `?– tchrist
Dec 16 '10 at 23:25