Regex for range 7.2-80.0, decimal length not required - regex

Anyone see what's wrong with the below query? Trying to confirm a number is between or equal to 7.2 and 80 in regex. Multiple decimals don't matter for example 8.999 is fine.
^(?:80(?:\.0)?|[8-79](?:\.[0-9])?|7?:\.[2-9])$

Your character class [8-79] is not a valid way of matching integers 8 through 79. An integer range in a character class must be a range of one-digit integers. A proper way to match integers 8 through 79 would be:
(?:[89]|[1-7][0-9])
Also, you are only matching up to one decimal place. For example,
80(?:\.0)?
will match 80 and 80.0, but not 80.00. If this could cause a problem for your application, you would instead want to use
80(?:\.0+)?
Using these concepts, I think this regex should do what you want:
^(?:80(?:\.0+)?|(?:[89]|[1-7][0-9])(?:\.[0-9]+)?|7(?:\.[2-9][0-9]*)?)$

Related

Integer range and multiple of

I have a number of fields I want to validate on text entry with a regex for both matching a range (0..120) and must be a multiple of 5.
For example, 0, 5, 25, 120 are valid. 1, 16, 123, 130 are not valid.
I think I have the regex for multiple of 5:
^\d*\d?((5)|(0))\.?((0)|(00))?$
and the regex for the range:
120|1[01][0-9]|[2-9][0-9]
However, I dont know how to combine these, any help much appreciated!
You can't do that with a simple regex. At least not the range-part (especially if the range should be generic/changeable).
And even if you manage to write the regex, it will be very complex and unreadable.
Write the validation on your own, using a parseStringToInt() function of your language and simple < and > checks.
Update: added another regex (see below) to be used when the range of values is not 0..120 (it can even be dynamic).
The second regex in the question does not match numbers smaller than 20. You can change it to match smaller numbers that always end in 0 or 5 to be multiple by 5:
\b(120|(1[01]|[0-9])?[05])\b
How it works (starting from inside):
(1[01]|[0-9])? matches 10, 11 or any one-digit number (0 to 9); these are the hundreds and tens in the final number; the question mark (?) after the sub-expression makes it match 0 or 1 times; this way the regex can also match numbers having only one digit (0..9);
[05] that follows matches 0 or 5 on the last digit (the units); only the numbers that end in 0 or 5 are multiple of 5;
everything is enclosed in parenthesis because | has greater priority than \b;
the outer \b matches word boundaries; they prevent the regex match only 1..3 digits from a longer number or numbers that are embedded in strings; it prevents it matching 15 in 150 or 120 in abc120.
Using dynamic range of values
The regex above is not very complex and it can be used to match numbers between 0 and 120 that are multiple of 5. When the range of values is different it cannot be used any more. It can be modified to match, lets say, numbers between 20 and 120 (as the OP asked in a comment below) but it will become harder to read.
More, if the range of allowed values is dynamic then a regex cannot be used at all to match the values inside the range. The multiplicity with 5 however can be achieved using regex :-)
For dynamic range of values that are multiple of 5 you can use this expression:
\b([1-9][0-9]*)?[05]\b
Parse the matched string as integer (the language you use probably provides such a function or a library that contains it) then use the comparison operators (<, >) of the host language to check if the matched value is inside the desired range.
At the risk of being painfully obvious
120|1[01][05]|[2-9][05]
Also, why the 2?

Regex for a valid 32-bit signed integer

I'm pretty sure this hasn't actually been answered yet on this site. For once and for all, what is the smallest regex that matches a numeric string that is in the range of a 32-bit signed integer, in the range -2147483648 to 2147483647.
I must use regex for validation - that is the only option available to me.
I have tried
\d{1,10}
but I can't figure out how to restrict it to the valid number range.
To aid developing in regex, it should match:
-2147483648
-2099999999
-999999999
-1
0
1
999999999
2099999999
2147483647
It should not match:
-2147483649
-2200000000
-11111111111
2147483648
2200000000
11111111111
I have set up an on-line live demo (on rubular) that has my attempt and the test cases above.
Note: The shortest regex that works will be accepted. Efficiency of regex will not be considered (unless there's a tie for shortest length).
I really hope it is just puzzler and no one will use regex for this problem in real world. Proper solution would be converting number from string to numeric type like BigInteger. This should allow us to check its range using proper methods or operators, like compareTo, >, <.
To make life easier you can use this page (dead link) to generate regex for ranges. So regex for range 0 - 2147483647 can look like
\b([0-9]{1,9}|1[0-9]{9}|2(0[0-9]{8}|1([0-3][0-9]{7}|4([0-6][0-9]{6}|7([0-3][0-9]{5}|4([0-7][0-9]{4}|8([0-2][0-9]{3}|3([0-5][0-9]{2}|6([0-3][0-9]|4[0-7])))))))))\b
(friendlier way)
\b(
[0-9]{1,9}|
1[0-9]{9}|
2(0[0-9]{8}|
1([0-3][0-9]{7}|
4([0-6][0-9]{6}|
7([0-3][0-9]{5}|
4([0-7][0-9]{4}|
8([0-2][0-9]{3}|
3([0-5][0-9]{2}|
6([0-3][0-9]|
4[0-7]
)))))))))\b
and range 0 - 2147483648
\b([0-9]{1,9}|1[0-9]{9}|2(0[0-9]{8}|1([0-3][0-9]{7}|4([0-6][0-9]{6}|7([0-3][0-9]{5}|4([0-7][0-9]{4}|8([0-2][0-9]{3}|3([0-5][0-9]{2}|6([0-3][0-9]|4[0-8])))))))))\b
So we can just combine these ranges and write it as
range of 0-2147483647 OR "-" range of 0-2147483648
which will give us
\b([0-9]{1,9}|1[0-9]{9}|2(0[0-9]{8}|1([0-3][0-9]{7}|4([0-6][0-9]{6}|7([0-3][0-9]{5}|4([0-7][0-9]{4}|8([0-2][0-9]{3}|3([0-5][0-9]{2}|6([0-3][0-9]|4[0-7])))))))))\b|-\b([0-9]{1,9}|1[0-9]{9}|2(0[0-9]{8}|1([0-3][0-9]{7}|4([0-6][0-9]{6}|7([0-3][0-9]{5}|4([0-7][0-9]{4}|8([0-2][0-9]{3}|3([0-5][0-9]{2}|6([0-3][0-9]|4[0-8])))))))))\b.
[edit]
Since Bohemian noticed in his comment final regex can be in form -?regex1|-2147483648 so here is little shorter version (also changed [0-9] to \d)
^-?(\d{1,9}|1\d{9}|2(0\d{8}|1([0-3]\d{7}|4([0-6]\d{6}|7([0-3]\d{5}|4([0-7]\d{4}|8([0-2]\d{3}|3([0-5]\d{2}|6([0-3]\d|4[0-7])))))))))$|^-2147483648$
If you will use it in Java String#matches(regex) method on each line you can also skip ^ and $ parts since they will be added automatically to make sure entire string matches regex.
I know this regex is very ugly, but just shows why regex is not good tool for range validation.
Edit:
This is the shortest regex you can get and the best way to do it:
We check every digit starting from the left, if it reaches it's limit and all the previous did, we put control on the next one.
for the range (-2147483647 to 2147483647) it could be a - signe or not. for -2147483648 it must be a - signe.
So finaly we get this:
^-?([0-9]{1,9}|[0-1][0-9]{9}|20[0-9]{8}|21[0-3][0-9]{7}|214[0-6][0-9]{6}|2147[0-3][0-9]{5}|21474[0-7][0-9]{4}|214748[0-2][0-9]{3}|2147483[0-5][0-9]{2}|21474836[0-3][0-9]|214748364[0-7])$|^(-2147483648)$
And this is a Live Demo
^(429496729[0-6]|42949672[0-8]\d|4294967[01]\d{2}|429496[0-6]\d{3}|42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|4[01]\d{8}|[1-3]\d{9}|[1-9]\d{8}|[1-9]\d{7}|[1-9]\d{6}|[1-9]\d{5}|[1-9]\d{4}|[1-9]\d{3}|[1-9]\d{2}|[1-9]\d|\d)$
Kindly try this i tested randomly not thoroughly.
only for the numbers above zero. add '-' and adjust last number pattern for negative numbers.
(^\d{1,9}$|^1\d{9}$|^20\d{8}$|^21[0-3]\d{7}$|^214[0-6]\d{6}$|^2147[0-3]\d{5}$|^21474[0-7]\d{4}$|^214748[0-2]\d{3}$|^2147483[0-5]\d{2}$|^21474836[0-3]\d$|^214748364[0-7]$)
one should never use regex for this type of work.

Regular Expression allow a decimal with up to 3 characters or integer with up to 2 characters

I'm trying to write a regex for a RegularExpressionValidator Control that will allow a decimal or integer with the following conditions:
Cannot be negative and zero.
Maximum string length including the optional decimal point is 3 characters and if only integers entered then 2 characters
Maximum number of decimal places is 1
So these are good....
0.1,
0.9,
9.0,
9.1,
2,
34
and these are bad.....
0,
-0,
-1,
-0.1,
.1,
.34,
9.01,
9.12,
345
Could you please help me out. I have looked at so many Regex samples but not able to build the right one which matches the above conditions.
Use the following regexp:
^(\d{1,2}\.?|\d\.\d)$
The first alternative allows 2-digit integer with an optional decimal point, the second allows a digit followed by 1 decimal place.
If it passes this validation, then test it against:
[^0]
to ensure it's not zero.
I have tried and come out with the below regex expression..which satisfies all the good values and bad values mentioned in the question.
^(([1-9])|([0-9][1-9])|([1-9][0-9])|([0-9][.][1-9])|([1-9][.][0-9]))$
I don't have much knowledge on regex, looking at some samples written the above regex found working fine. Please let me know your feedback on this, whether above regex can be written in this way and will it have any performance issues and if any other.

Regex to Limit Input To Only Numeric Values To 10 Occurences

I need help forming regex to limit user input to only numerics and only up to 10 occurrences.
I have regex that is working to keep input to numerics only, but I cannot limit it to up to 10.
Here is what I have:
^(0|[1-9][0-9]*)$
I am okay accepting negative numbers, decimals, and 0's. Any advice?
^\s*([0-9)+){0,10}\s*$
This basically says I want to 0 to 10 things, where each thing is all digits. I added the \s* on either side to allow the user to have put spaces before or after their numbers. This would accept things like
10 1231231 1231 1231 23112 123123
If what you really want is just a single number, that is only up to 10 digits, it is even easier:
^\s[0-9]{1,10}\s$
The regex you're looking for is this:
/(?=^[-+]?\d*\.?\d+$)^.{1,10}$/
Keep in mind that this regex will allow maximum length of input to 10 which includes optional + or - sign at start and a decimal point ..
you can try this:
^(?<=\s)(\-?[\d]{1,10}(?=\s))$
This fails as it has 11 digits
Debug.WriteLine(Regex.IsMatch("12345678901", #"^\d{1,10}$").ToString());
Posted the above answer before you clarified you want up to 10 set of numbers delimited by space.
Tested the accepted answer and in .NET Regex it fails for me.
Even fixing the syntax error it still does not parse by space
Give this a try
Debug.WriteLine(Regex.IsMatch(" 12345 678901 12 ", #"^\s*([+-]?\d+)(\s+[+-]?\d+){1,9}\s*$").ToString());

How to represent regex number ranges (e.g. 1 to 12)?

I'm currently using ([1-9]|1[0-2]) to represent inputs from 1 to 12. (Leading zeros not allowed.)
However it seems rather hacky, and on some days it looks outright dirty.
☞ Is there a proper in-built way to do it?
☞ What are some other ways to represent number ranges?
I tend to go with forms like [2-9]|1[0-2]? which avoids backtracking, though it makes little difference here. I've been conditioned by XML Schema to avoid such "ambiguities", even though regex can handle them fine.
Yes, the correct one:
[1-9]|1[0-2]
Otherwise you don't get the 10.
Here is the better answer, with exact match from 1 - 12.
(^0?[1-9]$)|(^1[0-2]$)
Previous answers doesn't really work well with HTML input regex validation, where some values like '1111' or '1212' will still treat it as a valid input.
​​​​
You can use:
[1-9]|1[012]
How about:
^[1-9]|10|11|12$
Matches 0-9 or 10 or 11 or 12. thats it, nothing else is matched.
You can try this:
^[1-9]$|^[1][0-2]$
Use the following pattern (0?[1-9]|1[0-2]) use this which will return values from 1 to 12 (January to December) even if it initially starts with 0 (01, 02, 03, ..., 09, 10, 11, 12)
The correct patter to validate numbers from 1 to 12 is the following:
(^[1-9][0-2]$)|(^[1-9]$)
The above expression is useful when you have an input with type number and you need to validate month, for example. This is because the input type number ignores the 0 in front of any number, eg: 01 it returns 1.
You can see it in action here: https://regexr.com/5hk0s
if you need to validate string numbers, I mean, when you use an input with type text but you expect numbers, eg: expiration card month, or months the below expression can be useful for you:
((^0[1-9]$)|(^1[0-2]$))
You can see it in action here https://regexr.com/5hkae
I hope this helps a lot because it is very tricky.
Regards.
In python this matches any number between 1 - 12:
12|11|10|9|8|7|6|5|4|3|2|1
The descending order matters. In ascending order 10, 11 and 12 would match 1 instead as regex usually pick the first matching value.