That's right. Unlike most questions, I am not trying to write a regular expression myself. I am trying to generate a regular expression (JavaScript flavoured, to be used in HTML5
's pattern
attribute).
Given an array of numbers, give a concise, fast, and correct regular expression that will only match the given input. I have already done part of the job, namely the ones [0-9]:
var ones = [0, 1, 2, 3, 4, 5, 8, 9],
onesRegex = "";
for (var i = 0; i < ones.length; i++) {
e = ones[i];
if (i > 0 && e == ones[i - 1] + 1) {
if (i != ones[i + 1] - 1) {
onesRegex += e + "]";
}
} else {
if (onesRegex != "") onesRegex += "|";
onesRegex += "[" + e + "-";
}
}
// Returns [0-5]|[8-9]
alert(onesRegex);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
This could then be used in an <input>
(yes, jQuery is allowed):
$("input").attr("pattern", onesRegex);
The problem I am experiencing is that I am not sure how to continue. Ones are easy enough, as you see above. However, things get increasingly more difficult as soon as you start adding digits because you have to take into account so many things. For instance, you can have [112, 358, 359, 360, 361] which should result in (112|(3(5[8-9]|6[0-1])))
which is already quite extensive for only five numbers.
For my project, the maximum value is 500, so all values < 1000
should be parsable.
I have written quite a bit, but there's a lot to be done -- I need to get the logic behind it. So far my idea is to split the number in ones, tens, and hundreds, and treat them accordingly. Additionally, the appropriate function can waterfall down to other functions. For instance, parsing the number 512 could split it down into 5 and 12, 12 will go down to a function for decimals, and so on. That's the main idea, but the logic and structure is missing.
Here is what I have so far, but I also provide a JSFiddle which is a bit easier to work with.
var arr = [0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 18, 19, 20, 21, 105, 106, 107, 256, 257, 258, 259, 260],
onesArray = [],
tensArray = [],
hundredsArray = [];
// MAIN
function regexGenerator() {
orderSplitter(arr);
// Do stuff
// Should return finished Regex as a string
}
// Split input array in ones (1 digit), tens (2 digits), hundreds (3 digits)
function orderSplitter(numberArray) {
$(numberArray).each(function(index, element) {
if (element < 10) {
onesArray.push(element);
} else if (element < 100 && element > 9) {
tensArray.push(element);
} else if (element < 1000 && element > 99) {
hundredsArray.push(element);
}
});
}
/* Following functions expect an array as input */
function onesToRegex(ones) {
var onesRegex = "";
for (var i = 0; i < ones.length; i++) {
var e = ones[i];
if (i > 0 && e == ones[i - 1] + 1) {
if (i != ones[i + 1] - 1) {
onesRegex += e + "]";
}
} else {
onesRegex += "[" + e + "-";
}
}
return onesRegex;
}
function tensToRegex(tens) {
var tensRegex = "";
for (var j = 0; j < tens.length; j++) {
var f = tens[j],
ten = Math.floor(f / 10),
one = f - (ten * 10);
}
return tensRegex;
}
function hundredsToRegex(hundreds) {
var hundredsRegex = "";
for (var k = 0; k < hundreds.length; k++) {
var g = tens[j],
hundred = Math.floor(g / 100),
ten = Math.floor((g - (hundred * 100)) / 10),
one = g - (ten * 10);
}
return hundredsRegex;
}