tags:

views:

149

answers:

4

I would like to write a regular expression to validate and input field against the following arguments:

  1. field is required (cannot be empty)
  2. field must not be a negative number
  3. field must be a validate decimal number to two decimals (eg. 1 or 1.3 or 1.23)
  4. field can be any valid number between 0 and 100 or an 'e'
A: 

Hmm does this work for you?

^((100|[0-9]{1,2})(\.[0-9]{1,2})?)|(e)$

Whay environment is this for? Any particular regex standard it must adhere to?

Constraints on numeric values (such as "> 100", or "<= 5.3") can make regexes rather complicated. These types of contraints are better checkedin application logic. Then you can have a simpler (and easier to understand) pattern:

^(([0-9]{1,3})(\.[0-9]{1,2})?)|(e)$

And then extract the capture group for the first 3 digits and validate that separately.

Edit: Ok I think this one should do it (last one because my eyes are getting tired):

^(100(\.0{1,2})?)|([0-9]{1,2})(\.[0-9]{1,2})?|(e)$

Will also allow 100.00 or 100.0

FrustratedWithFormsDesigner
This will match "199".
Max Shawabkeh
I think this will match 199, which is outside the range ?
Christopher Bruns
Ok, new pattern should avoid >100 properly.
FrustratedWithFormsDesigner
Nope, still wrong. That will match `100.99`. With just one more edit to get it working, you'll have the same answer as *Maxwell Troy Milton King* and *Max S.*. Perhaps it's time to pull the plug of this answer, eh? :)
Bart Kiers
Last try posted above.
FrustratedWithFormsDesigner
I still recommend deleting your post: now you are just repeating what has already been posted by others, but then in a far too verbose way (all the groups are cluttering up your regex, too much noise). Sorry, my -1 stays.
Bart Kiers
LOL, I know, but I still think my comment about numeric constraints is valid, and I think it was the first one there.
FrustratedWithFormsDesigner
Fair enough. You indeed raise(d) a good point about matching numerical ranges using regex (which I agree with you wholeheartedly, btw), but the fact that you posted a *not too good a regex* (and all attempts towards it), shadows that good remark about validating ranges. Of course, this is just my (not too humble) opinion. :)
Bart Kiers
A: 
^(?:100|\d{1,2}(?:\.\d{1,2})?|e)$
Maxwell Troy Milton King
What about his 'e'?
FrustratedWithFormsDesigner
No I didn't mean to escape '(' and '-' was a mistake.
Maxwell Troy Milton King
Arghh, bugger. You are right :(
Maxwell Troy Milton King
At least I should get a tiny credit for not creating back-references unnecessarily :-P
Maxwell Troy Milton King
But now you just nicked Max' solution! :)
Bart Kiers
+3  A: 

Regular expressions find great use in checking format, but you're wishing to use it to do a subset of floating point number parsing and bounds checking. Be kind to yourself and the person who will maintain your code after you're gone: check if it's an 'e', else read it into a float and check the bounds.

seanmac7577
+1  A: 

You can use: ^(100|\d{1,2}(\.\d{1,2})?|e)$

However, it would be simpler and more readable to use your language's float parsing/casting functions.

EDIT: Some variations based on the comments:

Allowing 100.0 and 100.00: ^(100(\.0{1,2})?|\d{1,2}(\.\d{1,2})?|e)$

Disallowing leading zeroes: ^(100(\.0{1,2})?|[1-9]?\d(\.\d{1,2})?|e)$

Max Shawabkeh
You'll want every alternation to have the `^` and `$`. In other words, use some grouping: `^(a|b|c)$`
Bart Kiers
Beat you to it. :D
Max Shawabkeh
Is 100.0 valid? What about 100.00?
D.Shawley
if you want to disallow leading/trailing zeroes, change `\d{1,2}(?:\.\d{1,2})?` to `[1-9]?\d(?:\.\d?[1-9])?`
rampion
Adding those is obviously trivial, but it's just another example of why you should use the right tool for the job, and parsing numerically bound values using regex is not the right tool for the job.
Max Shawabkeh
@D.Shawley, you can't ask of Max to tell you if `100.00` is valid input or not. Those question are best asked to the one asking the question (which I already did).
Bart Kiers