views:

292

answers:

3

What's the shortest regex that can match non-zero floating point numbers with any number of decimal places?

It should accept numbers like

-1
-5.9652
-7.00002
-0.8
-0.0500
-0.58000
0.01
0.000005
0.9900
5
7.5
7.005

but reject constructions such as

.
.02
-.
-.996
0
-0
0.
-0.
-0.000
0.00
--
..
+
+0
+1
+.
+1.26
,etc

I do not need support for the scientific notation, with e , E and such.
The language I'm using is C#, by the way.

A: 

This is the one I always use:

(\+|-)?([0-9]+\.?[0-9]*|\.[0-9]+)([eE](\+|-)?[0-9]+)?

Utilized in a PHP example:

<?php

$s= '1.234e4';

preg_match('~(\+|-)?([0-9]+\.?[0-9]*|\.[0-9]+)([eE](\+|-)?[0-9]+)?~', $s, $m);
print_r($m);

?>

Output:

Array
(
    [0] => 1.234e4
    [1] =>
    [2] => 1.234
    [3] => e4
)
pygorex1
+4  A: 
^-?(0\.\d*[1-9]|[1-9]\d*(\.\d+)?)$


EDIT Updated to reflect new requirements (last decimals can be zero)

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

(Shorter than using lookahead: ^-?(0\.(?=[1-9])\d*|[1-9]\d*(\.\d+)?)$.)


EDIT2 If e.g. 001.000 can pass

^-?(?=.*[1-9])\d+(\.\d+)?$
jensgram
Unfortunately I'm not familiar with the regex specifics in C#.
jensgram
Yet, fortunately, your syntax was correct. As an addendum, I would go for `^-?(0\.\d*[1-9]\d*|[1-9]\d*(\.\d+)?)$` instead, in order to preserve consistency of being able to enter final zeros after numbers in the (-1, 1) range too, not only after numbers that begin with a positive digit.
luvieere
Almost: rejects 0.10. Add another `\d*` after the first `[1-9]`.
Roger Pate
Yeah, I was not quite sure as to whether e.g. `0.10` should be rejected or not. I see now that I was less than consistent :)
jensgram
Bravo! The shortest working one by now! :D
luvieere
@luvieere I think my l33t regex0rz skillz are pretty much exhausted by now :) 26 chars seems to be my best shot.
jensgram
+1  A: 
-?(?!0)\d+(\.\d+)?

Note: Remember to put ^ $ if it's not done by your regexp matcher.

May I ask why the "shortest"? A pre-compiler RegExp or the same with non-matching groups could be faster. Also a test for zero could possibly be faster too.

Wernight
I want the shortest as it will go someplace in a XAML file and I want to keep it as brief as possible.
luvieere
A difference of 5-15 bytes matters enough to disregard performance and clarity?
Roger Pate
Characters in a regexp don't matter much once it's compiled. A RegExp evaluator is a finite state machine. There are many way to improve a FSM graph, and that's what some compilers do.In short, there is not a direct relation between the RegExp string length and it's evaluation speed.
Wernight
I'm not concerned about speed, but about visual compactness. I wouldn't want I big regex in XAML, it's hard to follow.
luvieere
What is the `!` sign? I've tested this and it doesn't work, it fails with 5.02 and many others...
luvieere
Correction: fails with 0.52
luvieere
`(?!...)` is a negative lookahead assertion. At that point, the `...` expression must not match for the assertion to succeed. http://www.regular-expressions.info/lookaround.html
Roger Pate
luvieere: Code-golf ("what's the shortest way to do ... regardless of other considerations") is **not** about making code that is easy to follow. Code should be concise but not necessarily the shortest possible. It definitely sounds like you won't be editing this regex often, so why do you care if it's 5 characters or 25? Take a look at a language like APL, which definitely produced *short* (in terms of characters) programs. http://en.wikipedia.org/wiki/APL_(programming_language)#Examples
Roger Pate
This matches 5.02 for me (not tested in C# though), lack of `(?!)` support might be your issue? The `.` should've been escaped. (That kind of error is easy to make when you worry about code size instead of other things... :P)
Roger Pate
"That kind of error is easy to make" ... tell me about it! And easy to correct as well, just click edit and go right at it.
luvieere
It accepts constructions like: -1. 5. Not very helpful...
luvieere
Incidentally, the `\.` only appeared as `.` because of formatting (fixed now). This won't accept "-1. 5", or did you mean something else?
Roger Pate
I ment`-1.`and`5.`
luvieere