I am looking for an efficient way to generically extract data from a string using another string as a template. Pseudocode:
var mystring = \"NET,1:1,0,ipv4,192.1
One solution is at http://jsfiddle.net/CrossEye/Kxe6W/
var templatizedStringParser = function(myTemplate, myString) {
var names = [];
var parts = myTemplate.replace( /\[([^\]]+)]/g, function(str, name) {
names.push(name);
return "~";
}).split("~");
var parser = function(myString) {
var result = {};
remainder = myString;
var i, len, index;
for (i = 0, len = names.length; i < len; i++) {
remainder = remainder.substring(parts[i].length);
index = remainder.indexOf(parts[i + 1]);
result[names[i]] = remainder.substring(0, index);
remainder = remainder.substring(index);
}
result[names[names.length - 1]] = remainder;
return result;
};
return myString ? parser(myString) : parser;
};
You can use it like this
console.log(templatizedStringParser(myTemplate, myString));
or this:
var parser = templatizedStringParser(myTemplate);
console.log(parser(myString));
There is almost certainly some cruft in there as I did this in a hurry. The use of the "~" might not work for you. And there are likely other problems if you have boundary issues, but it might cover many cases.
//This method obtains each lable in the template string
function getLables(patt, templateStr) {
var i = 0;
var tmp = patt.exec(templateStr);
var lables = new Array();
while(tmp) {
lables[i] = new String(tmp).replace("[", "").replace("]", "");
tmp = patt.exec(templateStr);
++i;
}
return lables;
}
function extract(_inputStr, _template) {
//Supposing the start string in template is NET
var startStr = "NET";
var inputStr = _inputStr.replace(startStr, "");
var template = "";
//You can add a control on the correctness of the template
if(_template.indexOf(startStr) != 0) {
return false;
//you could use a throw clausole, in order to use exceptions
} else {
template = _template.replace(startStr, "");
}
var patt = /\[[a-z | _]+\]/ig; //Pattern to recognize each [lable]
var delim = template.replace(patt, "[]").split("[]"); //Delimiter list
var lable = getLables(patt, template); //Lables list
var result = new Object();
var endIndex;
for(var i=0; i<lable.length; ++i) {
inputStr = inputStr.replace(delim[i], "");
endIndex = inputStr.indexOf(delim[i+1]);
if( (i+1) == lable.length ) {
result[lable[i]] = inputStr.substring(0, inputStr.length);
} else {
result[lable[i]] = inputStr.substring(0, endIndex)
inputStr = inputStr.replace(result[lable[i]], "");
}
}
return result;
}
In this example:
var template = "NET???[one]/[two]";
var inputStr = "NET???test/8";
JSON.stringify(extract(inputStr, template));
The result is:
{
"one":"test",
"two":"8"
}