Suppose I have an arbitrary regular expression. How I could calculate the length of string required for a match?
Examples (regex
=> minimum length of matchable string):
[0-9]{3},[0-9]{2}
=> 6[0-9]{4},[0-9]{2}
=> 7[0-9]{2}.[0-9]{3}.[0-9]{3}/[0-9]{4}-[0-9]{2}
=> 17[0-9]{3}.[0-9]{3}.[0-9]{3}-[0-9]{2}
=> 14[0-9]{2}/[A-Z]{2}/[0-9]{4}
=> 10
I also need a function which take as parameter a regex and a integer number between 1 and the size calculated with the function above (like position(regex, number)
), and return what the type of the character in that position (number, letter or symbol).
Examples:
- Example 1: Position 3 is a "number"
- Example 2: Position 3 is a "symbol"
- Example 5: Position 4 is a "letter"
UPDATE
the objective here is implement this:
function size_of(regex) {
//
}
function type_of(regex, posicao) {
//
}
function generate_string(tamanho) {
//
}
$(document).on('.valida', 'focus', function(){
var regex = $(this).attr('pattern');
var counter = 0;
var tam = size_of(regex);
var str = generate_string(tam);
$(this).val(str);
$(this).keypress(function(event){
var tecla = e.which;
if(typeof tecla == type_of(regex, counter)){
str = str + tecla;
counter++;
}
$(this).val(str);
});
});
UPDATE 2
some examples that would be useful:
1-> calculate the lengh: http://js.do/code/38693 (just need be more generic).
UPDATE 3 - FINAL CODE
the final code for the script above is that:
jsfiddle
http://jsfiddle.net/klebermo/f8U4c/78/
code
function parse(regexString){
var regex = /((?!\[|\{).(?!\]|\}))|(?:\[([^\]]+)\]\{(\d+)\})/g,
match,
model = [];
while (match = regex.exec(regexString)) {
if(typeof match[1] == 'undefined'){
for(var i=0;i<match[3];i++){
model.push(match[2]);
}
}else{
model.push(match[1]);
}
}
return model;
}
function replaceAt(s, n, t) {
return s.substring(0, n) + t + s.substring(n + 1);
}
function size_of(regex) {
var parsedRegexp = parse(regex);
return parsedRegexp.length;
}
function type_of(regex, posicao) {
var parsedRegexp = parse(regex);
var pos = parsedRegexp[posicao];
if(pos == '0-9')
return 'number';
if(pos == 'A-Z' || pos == 'a-z')
return 'string';
return pos;
}
function generate_string(regex, tamanho) {
var str = '';
for(var i=0; i<tamanho; i++) {
var type = type_of(regex, i);
if(type == 'number' || type == 'string')
str = str + '_';
else
str = str + type;
}
return str;
}
var counter;
var tam;
var str;
var regex;
$('.valida').each(function(){
$(this).on('focus', function(e){
regex = $(this).attr('pattern');
counter = 0;
tam = size_of(regex);
str = generate_string(regex, tam);
$(this).val(str);
});
$(this).on('keypress', function(e){
e.preventDefault();
var tecla = e.which;
if(tecla >= 48 && tecla <= 57)
var tecla2 = tecla - 48;
else
var tecla2 = String.fromCharCode(tecla);
result = $("<div>");
result.append( "tecla = "+tecla+"<br>" );
var t = type_of(regex, counter);
if(counter < tam) {
if(t != 'number' && t != 'string') {
str = replaceAt(str, counter, t);
counter++;
}
t = type_of(regex, counter);
if(typeof tecla2 == t) {
result.append( "tecla2 = "+tecla2+"<br>" );
str = replaceAt(str, counter, tecla2);
counter++;
}
}
result.append( "counter = "+counter+"<br>" );
$("#result").empty().append(result);
$(this).val(str);
});
});