Agreeing with all the caveats that a validation via regular expression is not the way, we can ramble on the subject.
It doesn’t hurt to remember, just because you can does not mean that must do.
I’ll repeat the warning I put out in this answer, because it costs nothing to alert:
You got the gun, I give you the ammo, but you decide whether to shoot yourself in the leg or not.
To reply from @Jjoao deals with closed intervals. I read that in your comments you quote that the interval is opened. So, I ponder, as it should be for open intervals?
Let’s talk here first in unit intervals, then extrapolate to some interval.
Open at the upper limit
The first case is if the upper limit is opened. For example, the range [42, 43)
accepts the value 42.999999
, but not 43.000000
.
To recognize this interval, with six decimal places, there is no secret. Just extrapolate the idea of @Jjoao to the desired number.
42(\.[0-9]{1,6})?
This expression is closed at the bottom limit and opens at the top. Accepts 42
to 42.999999
, as well as 42.0000
, but does not accept 43
.
Open at the lower limit
And at the lower limit? It was easy at the upper limit, will it also be at the lower?
For this, we need to recognize any string after the .
containing at least a non-zero number, limited to 6 numbers.
Basically this is the same question of generating a string of 1 to 6 digits in which at least one of these digits is non-zero. I got this to answer, I couldn’t simplify. I separated the alternatives below, the answer would be to put them all interspersed with |
.
[1-9][0-9]{0,5}
0[1-9][0-9]{0,4}
0{2}[1-9][0-9]{0,3}
0{3}[1-9][0-9]{0,2}
0{4}[1-9][0-9]{0,1}
0{5}[1-9]
In a way, for a total of m
decimal places at most, starting with z
left zeros, the formula for creating these subexpressions is:
0{z}[1-9][0-9]{0,m-z-1}
Whereas 0 <= z <= m - 1
, with z
and m
nonnegative integers.
Then, to recognize a number in the lower (and only lower) open range, the regex would be somewhat large. For (42,43]
, would be:
42\.([1-9][0-9]{0,5}|0[1-9][0-9]{0,4}|0{2}[1-9][0-9]{0,3}|0{3}[1-9][0-9]{0,2}|0{4}[1-9][0-9]{0,1}|0{5}[1-9])|43(\.0{1,6})?
If it were opened at both ends, the expression would not need to consider the integer 43
at the end:
42\.([1-9][0-9]{0,5}|0[1-9][0-9]{0,4}|0{2}[1-9][0-9]{0,3}|0{3}[1-9][0-9]{0,2}|0{4}[1-9][0-9]{0,1}|0{5}[1-9])
Uniting consecutive intervals
Well, we start with unit intervals, which start with integer numbers. And what would the union of these intervals look like if they were consecutive?
The first alternative would be to place the expressions of each grouped interval between (
relatives )
and interspersed with |
.
But we could do better, right?
The most well behaved interval is the closed interval at the lower limit but open at the upper limit. It contains a constant part (the whole part of the number) followed by the following expression:
(\.[0-9]{1,6})?
When we are interspersing several of these intervals, just put this expression on the right side and on the left side the separator constants by |
or some other expression that refers to it. For example, [32,43)
can be represented like this:
(3[2-9]|4[0-3])(\.[0-9]{1,6})?
On the right side, the magic expression representing the closed unit interval at the lower but open upper limit. On the right side, an expression representing all integers in the past interval.
If you need to deal with a closed range at the upper limit, just add the limit value followed by 0 to 6 zeros. As if it were a union between the closed interval at the beginning but open at the end and the individual number: [42,43) U {43}
42(\.[0-9]{1,6})?|43(\.0{1,6})?
Other unions may continue to apply normally, so do [32, 43]
is to make [32,42) U [42,43) U {43}
:
(3[2-9]|4[0-3])(\.[0-9]{1,6})?|43(\.0{1,6})?
For open interval, however, the formula will get big. I will not put as it would look the expression here, it would be unreadable of any sort. The thought, however, would be to isolate a single open unit interval at both ends, then treat the rest as closed intervals at the lower boundary and open at the upper. Type, (32,43]
can be interpreted as (32,33) U [33,43]
, or else as (32,33) U [33,43) U {43}
.
Does it need to be regex? Depending on the language, it is possible that you already have some simpler resource than regex.
– user28595
I work with online forms and can only create the rules by regex or else by validation rules. if it is not possible to do by regex try to create by validation rules that tell me if the value is >31 and <43
– Joana Nóbrega
but they asked me to try to do by regex first
– Joana Nóbrega
No time now, more gives an improved here:
^[3-4]{1}+[0-9]{1}.?[0-9]{6}$
. First character 3 or 4 + Second character between 0 and 9 the separating dot, after interrogation is optional 6 digits between 0 and 9– Paulo Ricardo
Online form? HTML? If so, Javascript is there to save your life. Just don’t forget that you need to validate the server nine as well, that client-level validation is only to improve the user experience, but cannot be used as the only way to verify/validate.
– Jefferson Quesado
Is the range open or closed? In comments it is written that the extreme values should not belong to the range
– Jefferson Quesado
@Pauloricardo There are some mistakes in your Regex: 1
{1}
is not quantifiable by+
. 2.
the endpoint matches any character and does not/.
the point literally and the?
corresponds to 0 or 1, but there should be a point. 3 Values such as 47.000000 and 30.000000 are accepted by the logic of regex used.– danieltakeshi
@danieltakeshi, I did not leave as an answer because I already knew there would be mistakes, I tried to leave only one starting point, in the intuition of helping despite this "crawling" with Regex, More thank you for the warning, I am already exercising the use of class, to understand a little better.
– Paulo Ricardo