I want a specific value, the value be only numbers and:
the length should be 11.
the first digit should be 0.
the second digit should be 1.
the third digit should be 0, 1, 2, 5.
then match any digit from the forth digit to the end.
if the third digit is 1, then the last two digits(10th, 11th) should be the same.
if the third digit is 2, the 8th, 9th digits should be the same.
Input string, and expected result.
01012345678 -----> allowed.
0101234a5678 -----> not allowed., letter exists.
01112345688 -----> allowed, 10th, 11st are the same
01112345677 -----> allowed, 10th, 11st are the same
01112345666 -----> allowed, 10th, 11st are the same
01112345689 -----> not allowed..10th, 11st different
01112345-678 -----> not allowed..hyphen exists.
01298765532 -----> allowed..8th, 9th are the same.
01298765732 -----> not allowed, 8th, 9th different.
01298765mm432 -----> not allowed, letter exists.
01500011122 -----> allowed..
020132156456136 -----> not allowed..more than 11 digit.
01530126453333 -----> not allowed..more than 11 digit.
00123456789 -----> not allowed.. second digit not 1.
This is my attempt at regex101,^01[0125][0-9]{8}$ https://regex101.com/r/cIcD0R/1 but it ignore specific cases also it works for specific cases.
You could make use of an alternation with 2 capture groups and backreferences:
^01(?:[05]\d{8}|1\d{6}(\d)\1|2\d{4}(\d)\2\d\d)$
Explanation
^ Start of string01 Match literally(?: Non capture group for the alternatives
[05]\d{8} Match either 0 or 5 and 8 digits| Or1\d{6}(\d)\1 Match 1, then 6 digits, capture a single digit in group 1 followed by a backreference to match the same digit| Or2\d{4}(\d)\2\d\d Match 2, then 4 digits, capture a single digit in group 2 followed by a backrefence to match the same digit and match the last 2 digits) Close the non capture group$ End of stringSee a regex101 demo
const regex = /^01(?:[05]\d{8}|1\d{6}(\d)\1|2\d{4}(\d)\2\d\d)$/;
[
"01012345678",
"0101234a5678",
"01112345688",
"01112345677",
"01112345666",
"01112345689",
"01112345-678",
"01298765532",
"01298765732",
"01298765mm432",
"01500011122",
"020132156456136",
"01530126453333",
"00123456789"
].forEach(s => console.log(`${s} => ${regex.test(s)}`))
If you're looking for a regex, purely to filter certain numbers without error messaging, this answer is probably not for you.
For validation purposes, a regex might not be the best way to go. If you would use one giant regex you would show one universal error message. This might leave a user confused since they partially complied with some of the criteria.
Instead split up the criteria so you can show a user relevant error messages.
function isValid(input, criteria) {
const errors = [];
for (const [isValid, error] of criteria) {
if (!isValid(input)) errors.push(error);
}
return [!errors.length, errors];
}
const criteria = [
[input => input.length === 11,
"must have a length of 11"],
[input => input.match(/^\d*$/),
"must only contain digits (0-9)"],
[input => input[0] === "0",
"must have 0 as 1st digit"],
[input => input[1] === "1",
"must have 1 as 2nd digit"],
[input => ["0","1","2","5"].includes(input[2]),
"must have 0, 1, 2 or 5 as 3rd digit"],
[input => input[2] !== "1" || input[9] === input[10],
"the 10th and 11th digit must be the same if the 3rd digit is 1"],
[input => input[2] !== "2" || input[7] === input[8],
"the 8th and 9th digit must be the same if the 3rd digit is 2"],
];
document.forms["validate-number"].addEventListener("submit", function (event) {
event.preventDefault();
const form = event.target;
const inputs = form.elements.inputs.value.split("\n");
inputs.forEach(input => console.log(input, ...isValid(input, criteria)));
});
<form id="validate-number">
<textarea name="inputs" rows="14" cols="15">01012345678
0101234a5678
01112345688
01112345677
01112345666
01112345689
01112345-678
01298765532
01298765732
01298765mm432
01500011122
020132156456136
01530126453333
00123456789</textarea>
<br />
<button>validate</button>
</form>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With