Parse config string into javascript/JSON [duplicate] - javascript

This question already has answers here:
javascript parser for a string which contains .ini data
(4 answers)
Closed 10 years ago.
I have a textarea where the user edits configurations. It is formatted like this:
foo = 'value'
bar = 2.1
john = false
Values can be false, true, floats or strings (no functions). I need to regexp this string to create something like:
{
foo: 'value',
bar: 2.1,
john: false
}
Is there a library or something for this?

I took this answer which should be a good beginning for your request, and added some further rules to handle the different data types, maybe this helps:
var data ="foo = 'value'";
data +="\n" + "bar = 2.1";
data += "\n" + "john = false";
function JSONFY(data){
var regex = {
section: /^\s*\[\s*([^\]]*)\s*\]\s*$/,
param: /^\s*([\w\.\-\_]+)\s*=\s*(.*?)\s*$/,
comment: /^\s*;.*$/
};
var value = {};
var lines = data.split(/\r\n|\r|\n/);
var section = null;
function handleSection(sec) {
var isFloat = /^(?:[1-9]\d*|0)?(?:\.\d+)?$/;
if(sec.match(isFloat)) {
return parseFloat(sec);
} else if(sec=='true') {
return true;
} else if(sec=='false') {
return false;
}
return sec.replace(/^['"]/,'').replace(/['"]$/,'');
}
lines.forEach(function(line){
if(regex.comment.test(line)){
return;
}else if(regex.param.test(line)){
var match = line.match(regex.param);
if(section){
value[section][match[1]] = match[2];
}else{
value[match[1]] = handleSection(match[2]);
}
}else if(regex.section.test(line)){
var match = line.match(regex.section);
value[match[1]] = {};
section = match[1];
}else if(line.length == 0 && section){
section = null;
};
});
return value;
}
console.log(JSONFY(data));
Here is the fiddle to test.

Depending on how much you can trust the input data, you can always write a simple function utilising code like the following (uses jQuery for simplicity's sake):
var lines = $('textarea').val().split('\n');
var output = '{';
$(lines).each(function(l){
output += '\n\t' + lines[l].replace(/(\w+)\s=\s(.*)/, '$1: $2,');
});
output = output.substring(0, output.length - 1);
output += '\n}';
$('textarea').val(output);
The main point here is that you will want to tweak the regex depending on how strict you want to be (i.e. allow whitespace to be optional with a ? after the \s or make sure the values are a specific format.

Related

javascript .data() cuts the string content by whitespace

So, I have this problem where I have a backwards-button in a webapplication. This is the javascript-code for the button:
function getPrevFunction()
{
localDBSelect("prevViews", function (prevViews)
{
if (prevViews)
{
var prevViewObject = $.parseJSON(prevViews);
var prevViewArray = prevViewObject['funcObjects'];
if (prevViewArray.length > 1)
{
var prevArrayIndex = prevViewArray.length - 2;
var actArrayIndex = prevViewArray.length - 1;
var prevFuncObject = prevViewArray[prevArrayIndex];
var prevFunc = prevFuncObject['function'];
var prevConfig = prevFuncObject['config'];
var inData = prevFuncObject['inData'];
prevViewArray.splice(actArrayIndex, 1);
if (inData !== "")
{
if (prevFunc !== "getGuiSiteList")
{
inData = "<div data-param=" + JSON.stringify(inData) + ">";
}
$('#fieldcontain')[prevFunc](inData, prevConfig);
}
else {
$('#fieldcontain')[prevFunc](prevConfig);
}
if (prevViewArray.length === 1)
{
setVisibilityForBackBtn(false); //If last..
}
prevViewObject['funcObjects'] = prevViewArray;
localDBInsert("prevViews", JSON.stringify(prevViewObject));
}
else {
setVisibilityForBackBtn(false);
}
$('#subcontainer').html("");
if(!$('#fieldcontain').is(":visible"))
{
$('#fieldcontain').show();
}
}
});
}
My problem is that I don't always get the entire content of the json-object. Eg; the json, at the beginning it looks like this:
input = {site: "GAV", location: "EG", set: "INVENTORY", binnum: "B01 T09"}
but after I have tried to fetch the json that is being passed as a data/attribute with an html-element like so:
var input = $(inData).data("param");
the value I recieve looks as follows:
input = "{"site":"GAV","location":"EG","set":"INVENTORY","binnum":"B01"
As you can se it has by some reason cut off all the characters after the whitespace, despite nothing happens between the fact that the last functions is added to the list, and that function is then called again, too be able to go backwards in the application.
I do realize that my explanation is messy and probably hard to understand, but this is the best that I can explain it.
I can provide more code if necessary.
So, I do need the entire json for the getPrevFunction (it is passed as "prevViews")
Use encodeURIComponent() and decodeURIComponent() like below
Setting the data
inData = "<div data-param=" + encodeURIComponent(JSON.stringify(inData)) + ">";
Getting the data
var input = JSON.parse(decodeURIComponent($(testDv).data('param')));
Now there will be no cuttings in the object due to whitespace.

How to replace parts of a string in Javascript?

I have a URL that I want to replace parts of, depending on the call I'm making.
For example, my URL is of the form
var url = "http://www.example.com/server/32/users/255667753/images/233.jpg"
I want to make calls to different URLs of the same form but with only the numbers changed. Currently, I am doing it like this
var urlPart1 = "http://www.example.com/server/"
var urlPart2 = "/users/";
var urlPart3 = "/images/";
var urlPart4 = ".jpg";
var sendRequestTo = urlPart1 + 32 + urlPart2 + 255667753 + urlPart3 + 233 + urlPart4.
However, is there a better way, like there is in Java?
You can use regexp
String.prototype.format = function() {
var regexp = /\{(\d+)\}/g, values = arguments;
return this.replace(regexp, function(match, index) {
return values[index];
});
};
var server = "http://www.example.com";
console.log("{0} is {1}".format("a", "b"));
console.log("{3}/server/{0}/users/{1}/images/{2}.jpg".format(32, 255667753, 233, server));
This approach is more like c# though which allows you to put the arguments in any order.
Since TypeScript is more on the side of object oriented programming, we need to extend interface. We need to extend the String interface and then we need to supply an implementation:
interface String {
format(...replacements: string[]): string;
}
if (!String.prototype.format) {
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}
And you can user anywhere this way:
var myStr = 'This is an {0} for {0} purposes: {1}';
alert(myStr.format('example', 'end'));
Cheers!
Declare this function globally somewhere
String.prototype.format = function (args) {
var newStr = this;
for (var key in args) {
newStr = newStr.replace('{' + key + '}', args[key]);
}
return newStr;
}
// This is generic url that will be formatted on the fly with dynamic numbers
var url = "http://www.example.com/server/{serverNo}/users/{userNo}/images/{imgNo}.jpg"
// call it with your dynamic numbers
url = url.format({serverNo:230948,userNo:123897,imgNo:1239378});
And finally your url will become
"http://www.example.com/server/230948/users/123897/images/1239378.jpg"
Happy coding.. :)

How to extract a REGEX query string result array into a Javascript object [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Use the get paramater of the url in javascript
How can I get query string values in JavaScript?
In Javascript, how can I get the parameters of a URL string (not the current URL)?
like:
www.domain.com/?v=123&p=hello
Can I get "v" and "p" in a JSON object?
Today (2.5 years after this answer) you can safely use Array.forEach. As #ricosrealm suggests, decodeURIComponent was used in this function.
function getJsonFromUrl(url) {
if(!url) url = location.search;
var query = url.substr(1);
var result = {};
query.split("&").forEach(function(part) {
var item = part.split("=");
result[item[0]] = decodeURIComponent(item[1]);
});
return result;
}
actually it's not that simple, see the peer-review in the comments, especially:
hash based routing (#cmfolio)
array parameters (#user2368055)
proper use of decodeURIComponent and non-encoded = (#AndrewF)
non-encoded + (added by me)
For further details, see MDN article and RFC 3986.
Maybe this should go to codereview SE, but here is safer and regexp-free code:
function getJsonFromUrl(url) {
if(!url) url = location.href;
var question = url.indexOf("?");
var hash = url.indexOf("#");
if(hash==-1 && question==-1) return {};
if(hash==-1) hash = url.length;
var query = question==-1 || hash==question+1 ? url.substring(hash) :
url.substring(question+1,hash);
var result = {};
query.split("&").forEach(function(part) {
if(!part) return;
part = part.split("+").join(" "); // replace every + with space, regexp-free version
var eq = part.indexOf("=");
var key = eq>-1 ? part.substr(0,eq) : part;
var val = eq>-1 ? decodeURIComponent(part.substr(eq+1)) : "";
var from = key.indexOf("[");
if(from==-1) result[decodeURIComponent(key)] = val;
else {
var to = key.indexOf("]",from);
var index = decodeURIComponent(key.substring(from+1,to));
key = decodeURIComponent(key.substring(0,from));
if(!result[key]) result[key] = [];
if(!index) result[key].push(val);
else result[key][index] = val;
}
});
return result;
}
This function can parse even URLs like
var url = "?foo%20e[]=a%20a&foo+e[%5Bx%5D]=b&foo e[]=c";
// {"foo e": ["a a", "c", "[x]":"b"]}
var obj = getJsonFromUrl(url)["foo e"];
for(var key in obj) { // Array.forEach would skip string keys here
console.log(key,":",obj[key]);
}
/*
0 : a a
1 : c
[x] : b
*/
You could get a JavaScript object containing the parameters with something like this:
var regex = /[?&]([^=#]+)=([^&#]*)/g,
url = window.location.href,
params = {},
match;
while(match = regex.exec(url)) {
params[match[1]] = match[2];
}
The regular expression could quite likely be improved. It simply looks for name-value pairs, separated by = characters, and pairs themselves separated by & characters (or an = character for the first one). For your example, the above would result in:
{v: "123", p: "hello"}
Here's a working example.

need to create a function that converts a range object that i created myself into a string? [duplicate]

This question already has an answer here:
when i run my code I get the following result []object object] [object object] but should be giving me an ordered array
(1 answer)
Closed 8 years ago.
below is the code that i used to create a range object within my overall programme
function parseRangeString(id, range) {
var myRangeString = range;
var myRangeStringArray = myRangeString.split(/[\s]+/);
var myMax;
var myMin;
var myMinOp;
var myMaxOp;
var myMaxInc = false;
var myMinInc = false;
var op1;
var op2;
var cons1;
var cons2;
op1 = myRangeStringArray[0];
cons1 = parseFloat(myRangeStringArray[1]);
if (myRangeStringArray[2] != null) {
op2 = myRangeStringArray[3];
cons2 = parseFloat(myRangeStringArray[4]);
}
if (cons1 < cons2) {
myMin = cons1;
myMinOp = op1;
myMax = cons2;
myMaxOp = op2;
} else {
myMin = cons2;
myMinOp = op2;
myMax = cons1;
myMaxop = op1;
}
if (myMaxOp.indexOf('=') != -1) {
myMaxInc = true;
}
if (myMinOp.indexOf('=') != -1) {
myMinInc = true;
}
firstRange = new Range(id, myMin, myMax, myMinInc, myMaxInc); //gives back a range object
return firstRange;
}
Now i need to make another function that converts the range object to string, help needed asap because i am stuck atm!
You can overwrite the standard toString function on your javascript objects to make them return whatever you want. Consider this example (demo):
var a = { some_property:'this could be coming from the user' }; // create a new object
a.toString = function(){
// in here, the "this" will point to the object in "a" variable. (well, at least mot of the times)
return this.some_property;
};
console.log(''+a); // force the object to string
If you create a lots of object like this, consider using the prototype of them to place the toString function, will be more efficient, MDN has great examples.
Well i guess i give the same answer every day. :)
JSON.stringify( range );

Difficulty writing a function to extract URL from array

I'm trying to extract a URL from an array using JS but my code doesn't seem to be returning anything.
Would appreciate any help!
var pages = [
"www.facebook.com|Facebook",
"www.twitter.com|Twitter",
"www.google.co.uk|Google"
];
function url1_m1(pages, pattern) {
var URL = '' // variable ready to accept URL
for (var i = 0; i < pages[i].length; i++) {
// for each character in the chosen page
if (pages[i].substr(i, 4) == "www.") {
// check to see if a URL is there
while (pages[i].substr(i, 1) != "|") {
// if so then lets assemble the URL up to the colon
URL = URL + pages[i].substr(i, 1);
i++;
}
}
}
return (URL);
// let the user know the result
}
alert(url1_m1(pages, "twitter")); // should return www.twitter.com
In your case you can use this:
var page = "www.facebook.com|Facebook";
alert(page.match(/^[^|]+/)[0]);
You can see this here
It's just example of usage RegExp above. Full your code is:
var pages = [
"www.facebook.com|Facebook",
"www.twitter.com|Twitter",
"www.google.co.uk|Google"
];
var parseUrl = function(url){
return url.match(/^(www\.[^|]+)+/)[0];
};
var getUrl = function(param){
param = param.toLowerCase();
var page = _(pages).detect(function(page){
return page.toLowerCase().search(param)+1 !== 0;
});
return parseUrl(page);
};
alert(getUrl('twitter'));
You can test it here
In my code I have used Underscore library. You can replace it by standard for or while loops for find some array item.
And of course improve my code by some validations - for example, for undefined value, or if values in array are incorrect or something else.
Good luck!
Im not sure exactly what you are trying to do, but you could use split() function
var pair = pages[i].split("|");
var url = pair[0], title=pair[1];

Categories