Regular expression 6 decimal places

Asked

Viewed 1,556 times

4

Can anyone tell me if it is possible to create a regular expression with the following characteristics:

  • value between 31.000000 and 43.000000
  • the value may have 6 decimal places, but must be in the range of 31 to 43.

Here’s what I got:

^(\+|-)?(\d\.\d{1,6}|[1-6]\d\.\d{1,6}|1[1-7]\d\.\d{1,6}|43\.0{1,6})$

it is possible to define a minimum value?

  • 3

    Does it need to be regex? Depending on the language, it is possible that you already have some simpler resource than regex.

  • 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

  • but they asked me to try to do by regex first

  • 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

  • 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.

  • Is the range open or closed? In comments it is written that the extreme values should not belong to the range

  • @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, 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.

Show 3 more comments

2 answers

11

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}.

  • Thanks! I adjusted to what was intended and I got it. (I also had to do for a negative interval).

  • Thank you for the answer and the explanation. I got a much better understanding of the regular expressions

  • @Jeffersonquesado, I liked your answer, even for wanting to give as much information as possible, however I think you complicated more than you needed. Usually things are simpler than they seem. Still very well :D

  • excellent Jefferson, clarified some doubts that had.

  • 1

    @Guilhermelautert, always answer, never simplify, and preferably complicate =D I am only remembering here the question they asked about recognizing leap years with regex

6


It is not the ideal way, but having to be:

^((3[1-9]|4[0-2])(\.\d{0,6})?|43(\.0{0,6})?)$
  • Thank you. I’ve already done :D

Browser other questions tagged

You are not signed in. Login or sign up in order to post.