First let’s see why your regex doesn’t work.
The clasps ([]
) correspond to a character class: they serve to indicate that you want any character within them.
For example, [abc]
means "the letter a
or the letter b
or the letter c
" (only one of them, any one serves). It is an expression that corresponds to only one character.
In case, is being used 0-9
, meaning "the digits from 0 to 9". Therefore, [0-9]
accepts any digit from 0 to 9. Note that the hyphen (-
) has a special meaning, as it serves to define an interval between two characters. As you also put another hyphen, but with backslash before (\-
), this happens to be interpreted as the hyphen character itself.
Therefore, [0-9\-]
means "one digit from 0 to 9 or a hyphen". Any of these characters serves, as we can see in the example below:
console.log(/[0-9\-]/.test('1')); // true
console.log(/[0-9\-]/.test('-')); // true
Already the quantifier +
means "one or more occurrences" than is immediately before it. So [0-9\-]+
means "one or more occurrences of digit or hyphen". That is, if it has multiple digits, it serves, and if it has multiple hyphens also serves (and any combination of these characters also serves).
console.log(/[0-9\-]+/.test('123112')); // true
console.log(/[0-9\-]+/.test('-----')); // true
console.log(/[0-9\-]+/.test('-1-3-432---111-')); // true
To get just a number from 0 to 9, just use [0-9]
or \d
(at the end of the reply I made a comment on [0-9]
versus \d
, since they are not always the same thing).
For the hyphen, you don’t need to put the backslash if it’s outside the brackets, just put -
and ready.
And to determine a specific amount, put this value between keys. In case, you want 12 digits, then just do [0-9]{12}
(exactly 12 occurrences of any digit from 0 to 9).
I also recommend using the markers ^
and $
, which means, respectively, the beginning and the end of the string. Thus, you ensure that the string only has what is determined inside the regex. So the regex for case 1 looks like this:
console.log(/^[0-9]-[0-9]{12}$/.test('1-167106651950')); // true
console.log(/^[0-9]-[0-9]{12}$/.test('123-167106651950')); // false
console.log(/^[0-9]-[0-9]{12}$/.test('1-A67106651950')); // false
If you don’t use the markers ^
and $
, can end up with false positives:
console.log(/[0-9]-[0-9]{12}/.test('abc1-167106651950def')); // true
Note that the string starts with abc
and ends with def
. Even so the regex returns true
, because it contains an excerpt that corresponds to the expression. Using ^
and $
you guarantee that she will only get what you specified.
For case 2, we can use the alternate operator |
for the options "SP" or "RJ": (SP|RJ)
.
For the number from 1 to 9, we use the brackets: [1-9]
. The two points are placed directly as :
, and for the other digits we use the quantity between keys, in the same way that was done in case 1. Also be sure to use the markers ^
and $
:
console.log(/^(SP|RJ)[1-9]:[0-9]{2}:[0-9]{6}$/.test('SP4:01:342310')); // true
console.log(/^(SP|RJ)[1-9]:[0-9]{2}:[0-9]{6}$/.test('RJ4:01:342310')); // true
console.log(/^(SP|RJ)[1-9]:[0-9]{2}:[0-9]{6}$/.test('AB4:01:342310')); // false
If you want a single regex that validates both cases, just join the previous expressions with |
.
In the example below I also use the class RegExp
Javascript, to avoid repeating code:
let re = RegExp(/^([0-9]-[0-9]{12})|((SP|RJ)[1-9]:[0-9]{2}:[0-9]{6})$/);
console.log(re.test('SP4:01:342310')); // true
console.log(re.test('RJ4:01:342310')); // true
console.log(re.test('1-167106651950')); // true
console.log(re.test('123-167106651950')); // false
console.log(re.test('AB4:01:342310')); // false
[0-9]
versus \d
Usually both are equivalent. The only detail is that depending on the language/engine/configuration, the \d
may also correspond to other characters representing digits, such as the characters ٠١٢٣٤٥٦٧٨٩
(see this answer for more details).
In the case of Javascript, this option is disabled by default, so either use one or the other:
let re = RegExp(/^(\d-\d{12})|((SP|RJ)[1-9]:\d{2}:\d{6})$/);
console.log(re.test('SP4:01:342310')); // true
console.log(re.test('RJ4:01:342310')); // true
console.log(re.test('1-167106651950')); // true
console.log(re.test('123-167106651950')); // false
console.log(re.test('AB4:01:342310')); // false
Notice I didn’t change the [1-9]
for \d
, since \d
takes all digits from 0 to 9, while [1-9]
does not include zero.
Thank you very much!
– Leonardo Vinicius
Thank you very much! It helped a lot in my understanding.
– Leonardo Vinicius