Question:
I recently needed a solution to place dots to separate numbers from three to three, backwards.
For example:
1000 => 1.000
100000 => 100.000
10000000 => 1.000.000
In an answer I found on the English Stackoverflow , the last solution was to use this regular expression:
function separarDeTresEmTres(numero)
{
return String(numero).split(/(?=(?:...)*$)/ ).join('.');
}
console.log(separarDeTresEmTres(1000));
console.log(separarDeTresEmTres(1000000));
console.log(separarDeTresEmTres(10000000));
But I didn't quite understand what magic was done by /(?=(?:...)*$)/
.
What's causing this regular expression to separate numbers from three to three, backwards? What is the explanation?
NOTE : I don't want answers explaining how to separate a number from three to three, because the regular expression I'm using is already doing that. The question here is specifically about how each part of this regular expression works. I don't want a solution to the problem without an explanation of what is happening.
Answer:
Well, let's build this regular expression:
-
.
– Recognizes any character. -
...
– Recognizes any three characters. -
(?:...)
– Group without capturing any three characters. Uncaptured groups start with(?:
and end with)
. -
(?:...)*
– Repetition. This*
indicates 0 or more repetitions. So that's several groups of three characters. -
$
– End of string. By ensuring that the end of the string is present, it is ensured that no characters can be left at the end. -
(?:...)*$
– Groups of three characters followed by the end of the string. This ensures that recognized groups must be at the end of the string, not the beginning. -
(?=(?:...)*$)
– Positive Lookahead – Forces recognition of what follows and looks for all places where the following expression matches something.
To understand this last point, let's assume the expression is (?=a(?:...)*$)
and the input string is 1234a567890
. In this case, the value recognized in the expression inside (?=
– )
would be a567890
, as this would be an a
followed by a number of characters multiple of 3, but recognition of the entire string captured by the positive lookahead (in this case the input complete) is forced anyway. Note that whole recognition happened even though the beginning of the next string did not enter the recognized part – this is what the positive lookahead does. Recognition also occurs multiple times because the regex inside the (?=
– )
is recognized in several different places – each three-character multi-length string stuck at the end of the string (including 0) preceded by anything is recognized.
-
The
/
before and after the regex is what Javascript uses to denote and delimit the regex. -
String(numero)
is a way to convert a number to a string. -
The
split
method chops the string where recognition takes place, so it will end up slicing the string into three characters from the end to the beginning because several different possibilities have been recognized and thus create an array of strings. -
The
join
is an array method that joins all the pieces into a single string by placing a separator between each piece, the result of which is returned withreturn
.