I need to accept a string that define how many ZIP code the user will use.
Examples:
1000:12001000,120001010:1015,1019,1025:1027 will return [1010,1011,1012,1013,1014,1015,1019,1025,1026,1027]I need to verify that string.
I used this to verify but it didnt work
/(\d{4}(:|,){0,1}\d{4})/gm
Start with a basic phrase to match either #### or ####:####
\d{4}(:\d{4})?
Then extend it to match any number of them in a comma-separated list:
\d{4}(:\d{4})?(,\d{4}(:\d{4})?)*
Finally, surround with ^ and $ to validate the entire line.
^(\d{4}(:\d{4})?)(,(\d{4}(:\d{4})?))*$
As much as I tried to simplify a Regex, here's a true validator for your specific strings.
Looks a bit long since it matches a range 1000→1200: 1(?:[01]\d{2}|200)
/^1(?:[01]\d{2}|200)(?::1(?:[01]\d{2}|200)(?!:)|,1(?:[01]\d{2}|200))*$/g
Regex101.com example and description
Without the range
the Regex is simpler but it will also match any four digit number like 0000, 9999:
/^\d{4}(?::\d{4}(?!:)|,\d{4})*$/g
Regex101.com example and description
Simplest - but not to be used a validator
The simpler solution would be
/^\d{4}(?:[,:]\d{4})*$/g
Regex101.com example and description
but as you can see it will match many wrong inputs like the invalid 1000:1005:1020 (two :)
You need to expand these matches after the match is found. I assume the string is validated before, if not use if (/^\d+(?:[:,]\d+)*$/.test(s)) { ... }.
let s = '1010:1015,1019,1025:1027';
const chunks = s.replace(/(\d+):(\d+)/g, (_,$1,$2) =>
Array.from(
new Array(Number($2)-Number($1)),
(x, i) =>
i + Number($1))
.join(",")).split(',');
console.log(chunks);
The Array.from(new Array(Number($2)-Number($1)), (x, i) => i + Number($1)) part generates a range of numbers between Group 1 and Group 2 values obtained with the /(\d+):(\d+)/g regex.