Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript percentage validation

I am after a regular expression that validates a percentage from 0 100 and allows two decimal places.

Does anyone know how to do this or know of good web site that has example of common regular expressions used for client side validation in javascript?

@Tom - Thanks for the questions. Ideally there would be no leading 0's or other trailing characters.

Thanks to all those who have replied so far. I have found the comments really interesting.

like image 931
Joel Cunningham Avatar asked Oct 23 '08 01:10

Joel Cunningham


5 Answers

I propose this one:

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

It matches 100, 100.0 and 100.00 using this part

^100(\.0{1,2})?$

and numbers like 0, 15, 99, 3.1, 21.67 using

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

Note what leading zeros are prohibited, but trailing zeros are allowed (though no more than two decimal places).

like image 59
Alexander Prokofyev Avatar answered Oct 31 '22 13:10

Alexander Prokofyev


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

This would match:
100.00
optional "1-9" followed by a digit (this makes the int part), optionally followed by a dot and two digits


From what I see, Greg Hewgill's example doesn't really work that well because parseFloat('15x') would simply return 15 which would match the 0<x<100 condition. Using parseFloat is clearly wrong because it doesn't validate the percentage value, it tries to force a validation. Some people around here are complaining about leading zeroes and some are ignoring trailing invalid characters. Maybe the author of the question should edit it and make clear what he needs.

like image 23
Tom Avatar answered Sep 18 '22 17:09

Tom


Rather than using regular expressions for this, I would simply convert the user's entered number to a floating point value, and then check for the range you want (0 to 100). Trying to do numeric range validation with regular expressions is almost always the wrong tool for the job.

var x = parseFloat(str);
if (isNaN(x) || x < 0 || x > 100) {
    // value is out of range
}
like image 34
Greg Hewgill Avatar answered Oct 31 '22 14:10

Greg Hewgill


This reminds me of an old blog Entry By Alex Papadimoulis (of The Daily WTF fame) where he tells the following story:

"A client has asked me to build and install a custom shelving system. I'm at the point where I need to nail it, but I'm not sure what to use to pound the nails in. Should I use an old shoe or a glass bottle?"

How would you answer the question?

  1. It depends. If you are looking to pound a small (20lb) nail in something like drywall, you'll find it much easier to use the bottle, especially if the shoe is dirty. However, if you are trying to drive a heavy nail into some wood, go with the shoe: the bottle with shatter in your hand.

  2. There is something fundamentally wrong with the way you are building; you need to use real tools. Yes, it may involve a trip to the toolbox (or even to the hardware store), but doing it the right way is going to save a lot of time, money, and aggravation through the lifecycle of your product. You need to stop building things for money until you understand the basics of construction.

This is such a question where most people sees it as a challenge to come up with the correct regular expression to solve the problem, but it would be much better to just say that using regular expressions are using the wrong tool for the job.

The problem when trying to use regex to validate numeric ranges is that it is hard to change if the requirements for the allowed range is changes. Today the requirement may be to validate numbers between 0 and 100 and it is possible to write a regex for that which doesn't make your eyes bleed. But next week the requirment maybe changes so values between 0 and 315 are allowed. Good luck altering your regex.

The solution given by Greg Hewgill is probably better - even though it would validate "99fxx" as "99". But given the circumstances that might actually be ok.

like image 5
mlarsen Avatar answered Oct 31 '22 14:10

mlarsen


Given that your value is in str

str.match(/^(100(\.0{1,2})?|([0-9]?[0-9](\.[0-9]{1,2})))$/)
like image 1
Czimi Avatar answered Oct 31 '22 14:10

Czimi