My answer complements the response from Paul R. F. Amorim, showing how what he said is applied to the Regex Expression posed in the question.
Note that in a Regex you create the Groups in parentheses, what is within parentheses will be captured by the group; and, each Group has a numerical id so that we can reference it. The id 0
corresponds to the match of the whole regex; we can know the ids of the Groups within the regex expression by observing the order - from left to right - in which the parentheses are opened:
In Regex a(b|c)(apartamento|ca(sa|rro))
:
- the Group of id
1
is (b|c)
who will return b
or c
;
- the Group of id
2
is (apartamento|ca(sa|rro))
who will return apartamento
or casa
or carro
;
- the Group of id
3
is (sa|rro)
who will return sa
or rro
(or will be undefined if id group 2
contains apartamento
).
If you want a Group not to have a reference, ie an id, you can use (?:)
which creates a non-capturing group, as explained in that reply of Soen (in English).
Your Regex starts like this: (^(?:\d{4}([-/.])...
See that the Group ([-/.])
has the id 2
, because before him we have a non-capturing group (?:\d{4}...
and a Group of id 1
which is opened by the first parenthesis(^...
.
Date Separator can be obtained by id 2
which is the Group reference "([-/.])
", who will return -
or /
or .
. To refer to this group it is sufficient to make \2
as @Paulo explained.
Currently your Regex presents several times Groups equal to "([-/.])
", we can simply keep the first of these (which has id 2
, as I explained above) and replace the others by his reference which is \2
; i decided to keep the reference within Groups to facilitate, so that, we have a Before/After like this:
Before: (^(?:\d{4}([-/.])...([-/.])...([-/.])...([-/.])...
Afterward: (^(?:\d{4}([-/.])...(\2)...(\2)...(\2)...
With this, Regex will only match if all separators are equal to the one captured by the id Group 2
, so that we only validate dates that don’t mix different separators. Then there will be match on a date like 2000/02/28
or 2000-02-28
, but there will be no match on a date like 2000/02-28
.
In the end, your Regex looks like this:
(^(?:\d{4}([-/.])(?:(?:(?:(?:0?[13578]|1[02]|j(?:an|ul)|[Mm]a[ry]|[Aa]ug|[Oo]ct|[Dd]ec)(\2)(?:0?[1-9]|[1-2][0-9]|3[01]))|(?:(?:0?[469]|11|[Aa]pr|[Jj]un|[Ss]ep|[Nn]ov)(\2)(?:0?[1-9]|[1-2][0-9]|30))|(?:(0?2|[Ff]eb)(\2)(?:0?[1-9]|1[0-9]|2[0-8]))))|(?:(?:\d{2}(?:0[48]|[2468][048]|[13579][26]))|(?:(?:[02468][048])|[13579][26])00)([-/.])(0?2|[Ff]eb)(\7)29)$)
Note that at the end of the expression I used a reference to the id Group 7
instead of the id group 2
: ...(\7)29)$)
; this was necessary due to the specific characteristics of its Regex, which gives a different treatment for the days 29 of the month February. This becomes clearer in the Debuggex:
See in the image that it would not work to do the Group 9
(Ref 4
) reference the Group 2
because the Group 2
will be undefined when the date is February 29th, but, we do the Group 9
reference the Group 7
that will not be indefinite on the dates of 29 of February.
Regardless of the correct answer, I don’t think validating dates at this level is a cool thing to implement as a regular expression. I wrote a lot about it here: https://answall.com/a/272541/500
– jsbueno
friend, I’m sorry but I don’t understand. You can exemplify the entries and validations?
– Paz
@Peace a regex validates the following data entry: yyyy/mm/dd or 2000/02/29 or 2000/Feb/29 or 2000/Feb/29 however how I am using different tabs precise force with backreference because the regex is validating the following entry: 2000/02-29 or 2000/Feb.29 or 2000-Feb.29 when it should validate only with some of the tabs...
– dark777
@jsbueno based on what you said there I was trying to force with backreference but did not understand very well how to find the values or understand the groups to determine the values of backreferences... To connected that is not the best solution I am studying regex by issues of topic of a book that a teacher passed to me when I was doing in the facul the same is of C however as I am studying c++ so I sought to study the Std::regex.
– dark777