Match 0 to 100 or 0% to 100% using regex
I'm trying to match the following, and i'm having a difficult time doing so.
I want to allow 0 to 100, or 0% to 100%. In my textfield, i strip the % out, so if they put in 100, it won't fail at the regex and skip the strip.
Therefore, i'd need a regex to allow 0 to 100 or 0% to 100%. 101 or 101% is invalid.
Presently, i have the following
(?:^((\\%)?100(\\%)?$)|(?:^(\\%)?[0-9]{1,2}(\\%)?)((\\.|,)?[0-9]+)?$)
But that allows 101 but not 101%
Please help! Any help wou开发者_开发百科ld be greatly appreciated.
You're trying to use regex to do something that regex isn't meant to do. You have the javascript and python tags; you should use regex to ensure that the input is a number, and then use javascript or python to determine whether the number is too big or too small. It will be much easier that way.
Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have two problems.. - Jamie Zawinski 1997
In all seriousness, you are trying to do something that Regular Expressions aren't intended to do, which is perform logic. What you are asking is, does this string of characters contain a number, which is fine and if it does, is it >= 0 && <= 100
which isn't something a regular expression can or should be doing.
While the expression ^(\d{1,2}|100)%?$ will work to tell you if the input matches the pattern, and let you pull the number out using the group. The fact that the result falls into the >=0 && <= 100
range is a side effect. This apparent range checking behavior won't work for any other arbitrary range of numbers. Side effects should be avoided for maintainable code.
Is it the optimal solution? Is the intention obvious from just looking at the expression? I would argue no, not without some comments describing the intent.
JavaScript
I think a better more maintainable solution would be to use the parseInt()
function and then explicitly compare the result to >= 0
and <= 100
. Explicit is Better than Implicit and is more self documenting.
Python
You will still have to resort to a regular expression to validate the format and extract only the numbers and convert that using int()
, testing against the valid range would be redundant but also more explicit. Using the regular expression might not be such a bad option in this case, as long as you comment the intention of the use of the regular expression.
/^(100|[0-9]{1,2})%?$/
- either '100' or any number consisting of one or two digits
- possibly followed by a percent sign.
Test it here: http://jsbin.com/azeya3.
Oh yes, and the first capture contains the number.
use on javascript "parseInt"
parseInt does following:
"100" -> 100
"10k" -> 10
"100%" -> 100
after this, check if your number is smaller than 101.
example...
function parsePerc(value) {
return parseInt(value) < 101;
}
The question is tagged "python", so I'll answer in Python:
def is0to100(num):
try:
return 0 <= int(num.rstrip('%')) <= 100
except ValueError:
return False
This returns True if the passed-in value, minus the possible trailing '%', is a valid integer between 0 and 100. I didn't benchmark it, but I'd put money that it's way faster than a regexp.
In the spirit of @eykanal's answer, here's a regex:
(\d{1,3})%?
works for me in Python with this.
My test text was:
101
100
100%
101%
0%
0
50%
That will get you just the number, which you can then parse and decide whether or not it's in your acceptable range.
First, I agreed with eykanal and Jarrod Roberson
But then, it's so simple with a regex that I doesn't agree more and that it's the better solution according to me:
'(\d\d?|100)(?!\d)\Z' and use of match()
I think that presenting in first position \d\d?
for detecting numbers < 100 , and in second position the number 100
alone, is of more natural logic.
Also \d\d?
is shorter and more rapidly understood than \d{1,2}
EDIT
better :
'(\d\d?|100)\D?\Z'
But these RE are for detection. Since the aim is to verify, this one is enough:
'(\d\d?|100)\Z'
Match 0 to 100
^100$|^[123456789][0-9]$|^[0-9]$
Match 0% to 100%
^100[%]$|^[123456789][0-9][%]$|^[0-9][%]$
精彩评论