I am trying to validate a comma separated list of numbers 1-384 unique (not repeating).
i.e.
- 1, 2, 3, 5, 6, 7, 9 is valid
- 1-3, 5-7, 9 is valid
- 2, 2, 6 is invalid
- 2, is invalid
- 1, 2, 3, 4, 15, 6, 7, 385 is invalid because the last number is more than 384
I have tried the following RegEx pattern, but is not sufficient:
/^(?!.*(b(?:[1-9]|[1-2]d|3[0-1])b).*b1b)(?:[1-9]|[1-2]d|3[0-1])(?:,(?:[1-9]|[1-2]d|3[0-1]))*$/
Advertisement
Answer
You can try this-
function isValid(str) { let lower = 1, upper = 384; // Removing the unnecessary spaces str = str.replace(/s/g, ''); // Split the string by comma (,) const nums = str.split(','); const track = {}; // Visit the numbers for (const num of nums) { // Check if any number contains a dash (-) if (/-/.test(num)) { // If has dash then split by dash and get the upper and lower bounds. const [l, u] = num.split('-').map(x => x * 1); // Visit from lower to upper bound for (let i = l; i <= u; i++) { // If any number of the range doesn't exceed the upper // or lower bound i.e. [1, 384] range and did not // appear before then track this number. // otherwise return false i.e. mark it as invalid. if (i >= lower && i <= upper && track[i] === undefined) { track[i] = true; } else { return false; } } } else { // Checking again if it exceed the range [1, 384] or appears before. if (num * 1 >= lower && num * 1 <= upper && track[num] === undefined) { track[num] = true; } else { return false; } } } // If everything okay then return true, i.e. valid. return true; } const strs = [ '1, 2, 3, 5, 6, 7, 9', '1-3, 5-7, 9', '2, 2, 6', '2,', '1, 2, 3, 4, 15, 6, 7, 385', '1-4, 3, 7-9, 10', '1-100, 102, 123', '1-100, 102, 99' ]; for (const str of strs) { console.log(str + ' => ' + (isValid(str) ? 'Valid': 'Invalid')); }
.as-console-wrapper{min-height: 100%!important; top: 0}